@skillkit/core 1.7.9 → 1.7.10
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/README.md +2 -2
- package/dist/index.d.ts +856 -1
- package/dist/index.js +1313 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -713,8 +713,8 @@ function validateSkill(skillPath) {
|
|
|
713
713
|
return { valid: errors.length === 0, errors, warnings };
|
|
714
714
|
}
|
|
715
715
|
function isPathInside(child, parent) {
|
|
716
|
-
const
|
|
717
|
-
return !
|
|
716
|
+
const relative5 = child.replace(parent, "");
|
|
717
|
+
return !relative5.startsWith("..") && !relative5.includes("/..");
|
|
718
718
|
}
|
|
719
719
|
|
|
720
720
|
// src/config.ts
|
|
@@ -18516,11 +18516,1316 @@ function getQualityGrade(score) {
|
|
|
18516
18516
|
function isHighQuality(score) {
|
|
18517
18517
|
return score.overall >= 80 && score.warnings.length <= 2;
|
|
18518
18518
|
}
|
|
18519
|
+
|
|
18520
|
+
// src/primer/types.ts
|
|
18521
|
+
import { z as z6 } from "zod";
|
|
18522
|
+
var PrimerLanguage = z6.enum([
|
|
18523
|
+
"typescript",
|
|
18524
|
+
"javascript",
|
|
18525
|
+
"python",
|
|
18526
|
+
"go",
|
|
18527
|
+
"rust",
|
|
18528
|
+
"java",
|
|
18529
|
+
"kotlin",
|
|
18530
|
+
"swift",
|
|
18531
|
+
"ruby",
|
|
18532
|
+
"php",
|
|
18533
|
+
"csharp",
|
|
18534
|
+
"cpp"
|
|
18535
|
+
]);
|
|
18536
|
+
var PackageManager = z6.enum([
|
|
18537
|
+
"npm",
|
|
18538
|
+
"pnpm",
|
|
18539
|
+
"yarn",
|
|
18540
|
+
"bun",
|
|
18541
|
+
"pip",
|
|
18542
|
+
"poetry",
|
|
18543
|
+
"uv",
|
|
18544
|
+
"cargo",
|
|
18545
|
+
"go",
|
|
18546
|
+
"maven",
|
|
18547
|
+
"gradle",
|
|
18548
|
+
"composer",
|
|
18549
|
+
"bundler",
|
|
18550
|
+
"cocoapods",
|
|
18551
|
+
"swift-package-manager",
|
|
18552
|
+
"nuget"
|
|
18553
|
+
]);
|
|
18554
|
+
var CodeConvention = z6.object({
|
|
18555
|
+
namingStyle: z6.enum(["camelCase", "snake_case", "PascalCase", "kebab-case"]).optional(),
|
|
18556
|
+
indentation: z6.enum(["tabs", "spaces-2", "spaces-4"]).optional(),
|
|
18557
|
+
quotes: z6.enum(["single", "double"]).optional(),
|
|
18558
|
+
semicolons: z6.boolean().optional(),
|
|
18559
|
+
trailingCommas: z6.enum(["none", "es5", "all"]).optional(),
|
|
18560
|
+
maxLineLength: z6.number().optional()
|
|
18561
|
+
});
|
|
18562
|
+
var ProjectStructure = z6.object({
|
|
18563
|
+
type: z6.enum(["flat", "src-based", "monorepo", "packages"]).optional(),
|
|
18564
|
+
srcDir: z6.string().optional(),
|
|
18565
|
+
testDir: z6.string().optional(),
|
|
18566
|
+
docsDir: z6.string().optional(),
|
|
18567
|
+
configDir: z6.string().optional(),
|
|
18568
|
+
hasWorkspaces: z6.boolean().default(false),
|
|
18569
|
+
workspaces: z6.array(z6.string()).optional()
|
|
18570
|
+
});
|
|
18571
|
+
var CIConfig = z6.object({
|
|
18572
|
+
provider: z6.enum(["github-actions", "gitlab-ci", "circleci", "jenkins", "travis", "azure-pipelines"]).optional(),
|
|
18573
|
+
hasCI: z6.boolean().default(false),
|
|
18574
|
+
hasCD: z6.boolean().default(false),
|
|
18575
|
+
configFile: z6.string().optional()
|
|
18576
|
+
});
|
|
18577
|
+
var EnvConfig = z6.object({
|
|
18578
|
+
hasEnvFile: z6.boolean().default(false),
|
|
18579
|
+
hasEnvExample: z6.boolean().default(false),
|
|
18580
|
+
envVariables: z6.array(z6.string()).optional()
|
|
18581
|
+
});
|
|
18582
|
+
var DockerConfig = z6.object({
|
|
18583
|
+
hasDockerfile: z6.boolean().default(false),
|
|
18584
|
+
hasCompose: z6.boolean().default(false),
|
|
18585
|
+
baseImage: z6.string().optional()
|
|
18586
|
+
});
|
|
18587
|
+
var PrimerAnalysis = z6.object({
|
|
18588
|
+
project: z6.object({
|
|
18589
|
+
name: z6.string(),
|
|
18590
|
+
description: z6.string().optional(),
|
|
18591
|
+
version: z6.string().optional(),
|
|
18592
|
+
type: z6.string().optional(),
|
|
18593
|
+
license: z6.string().optional(),
|
|
18594
|
+
repository: z6.string().optional()
|
|
18595
|
+
}),
|
|
18596
|
+
languages: z6.array(Detection).default([]),
|
|
18597
|
+
packageManagers: z6.array(PackageManager).default([]),
|
|
18598
|
+
stack: ProjectStack,
|
|
18599
|
+
patterns: ProjectPatterns.optional(),
|
|
18600
|
+
structure: ProjectStructure.optional(),
|
|
18601
|
+
conventions: CodeConvention.optional(),
|
|
18602
|
+
ci: CIConfig.optional(),
|
|
18603
|
+
env: EnvConfig.optional(),
|
|
18604
|
+
docker: DockerConfig.optional(),
|
|
18605
|
+
buildCommands: z6.object({
|
|
18606
|
+
install: z6.string().optional(),
|
|
18607
|
+
build: z6.string().optional(),
|
|
18608
|
+
test: z6.string().optional(),
|
|
18609
|
+
lint: z6.string().optional(),
|
|
18610
|
+
format: z6.string().optional(),
|
|
18611
|
+
dev: z6.string().optional(),
|
|
18612
|
+
start: z6.string().optional()
|
|
18613
|
+
}).optional(),
|
|
18614
|
+
importantFiles: z6.array(z6.string()).default([]),
|
|
18615
|
+
codebaseSize: z6.object({
|
|
18616
|
+
files: z6.number().optional(),
|
|
18617
|
+
lines: z6.number().optional(),
|
|
18618
|
+
directories: z6.number().optional()
|
|
18619
|
+
}).optional()
|
|
18620
|
+
});
|
|
18621
|
+
var AGENT_INSTRUCTION_TEMPLATES = {
|
|
18622
|
+
"claude-code": {
|
|
18623
|
+
agent: "claude-code",
|
|
18624
|
+
filename: "CLAUDE.md",
|
|
18625
|
+
format: "markdown",
|
|
18626
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "structure", "guidelines"]
|
|
18627
|
+
},
|
|
18628
|
+
"cursor": {
|
|
18629
|
+
agent: "cursor",
|
|
18630
|
+
filename: ".cursorrules",
|
|
18631
|
+
format: "markdown",
|
|
18632
|
+
sectionOrder: ["overview", "stack", "conventions", "guidelines"]
|
|
18633
|
+
},
|
|
18634
|
+
"github-copilot": {
|
|
18635
|
+
agent: "github-copilot",
|
|
18636
|
+
filename: ".github/copilot-instructions.md",
|
|
18637
|
+
format: "markdown",
|
|
18638
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "structure", "guidelines"]
|
|
18639
|
+
},
|
|
18640
|
+
"codex": {
|
|
18641
|
+
agent: "codex",
|
|
18642
|
+
filename: "AGENTS.md",
|
|
18643
|
+
format: "markdown",
|
|
18644
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "structure", "guidelines"]
|
|
18645
|
+
},
|
|
18646
|
+
"gemini-cli": {
|
|
18647
|
+
agent: "gemini-cli",
|
|
18648
|
+
filename: "GEMINI.md",
|
|
18649
|
+
format: "markdown",
|
|
18650
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "structure", "guidelines"]
|
|
18651
|
+
},
|
|
18652
|
+
"windsurf": {
|
|
18653
|
+
agent: "windsurf",
|
|
18654
|
+
filename: ".windsurfrules",
|
|
18655
|
+
format: "markdown",
|
|
18656
|
+
sectionOrder: ["overview", "stack", "conventions", "guidelines"]
|
|
18657
|
+
},
|
|
18658
|
+
"opencode": {
|
|
18659
|
+
agent: "opencode",
|
|
18660
|
+
filename: "AGENTS.md",
|
|
18661
|
+
format: "markdown",
|
|
18662
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "structure", "guidelines"]
|
|
18663
|
+
},
|
|
18664
|
+
"trae": {
|
|
18665
|
+
agent: "trae",
|
|
18666
|
+
filename: ".trae/rules/project_rules.md",
|
|
18667
|
+
format: "markdown",
|
|
18668
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "guidelines"]
|
|
18669
|
+
}
|
|
18670
|
+
};
|
|
18671
|
+
|
|
18672
|
+
// src/primer/analyzer.ts
|
|
18673
|
+
import { existsSync as existsSync35, readFileSync as readFileSync27, readdirSync as readdirSync10 } from "fs";
|
|
18674
|
+
import { join as join36, basename as basename13, relative as relative4, sep as sep2 } from "path";
|
|
18675
|
+
var PACKAGE_MANAGER_FILES = {
|
|
18676
|
+
"package-lock.json": "npm",
|
|
18677
|
+
"pnpm-lock.yaml": "pnpm",
|
|
18678
|
+
"yarn.lock": "yarn",
|
|
18679
|
+
"bun.lockb": "bun",
|
|
18680
|
+
"requirements.txt": "pip",
|
|
18681
|
+
"Pipfile.lock": "pip",
|
|
18682
|
+
"poetry.lock": "poetry",
|
|
18683
|
+
"uv.lock": "uv",
|
|
18684
|
+
"Cargo.lock": "cargo",
|
|
18685
|
+
"go.sum": "go",
|
|
18686
|
+
"pom.xml": "maven",
|
|
18687
|
+
"build.gradle": "gradle",
|
|
18688
|
+
"build.gradle.kts": "gradle",
|
|
18689
|
+
"composer.lock": "composer",
|
|
18690
|
+
"Gemfile.lock": "bundler",
|
|
18691
|
+
"Podfile.lock": "cocoapods",
|
|
18692
|
+
"Package.resolved": "swift-package-manager",
|
|
18693
|
+
"packages.lock.json": "nuget"
|
|
18694
|
+
};
|
|
18695
|
+
var CI_CONFIG_FILES = {
|
|
18696
|
+
".github/workflows": "github-actions",
|
|
18697
|
+
".gitlab-ci.yml": "gitlab-ci",
|
|
18698
|
+
".circleci/config.yml": "circleci",
|
|
18699
|
+
"Jenkinsfile": "jenkins",
|
|
18700
|
+
".travis.yml": "travis",
|
|
18701
|
+
"azure-pipelines.yml": "azure-pipelines"
|
|
18702
|
+
};
|
|
18703
|
+
var IMPORTANT_CONFIG_FILES = [
|
|
18704
|
+
"package.json",
|
|
18705
|
+
"tsconfig.json",
|
|
18706
|
+
"pyproject.toml",
|
|
18707
|
+
"Cargo.toml",
|
|
18708
|
+
"go.mod",
|
|
18709
|
+
".eslintrc.js",
|
|
18710
|
+
".eslintrc.json",
|
|
18711
|
+
"eslint.config.js",
|
|
18712
|
+
".prettierrc",
|
|
18713
|
+
"prettier.config.js",
|
|
18714
|
+
"biome.json",
|
|
18715
|
+
"tailwind.config.js",
|
|
18716
|
+
"tailwind.config.ts",
|
|
18717
|
+
"vite.config.ts",
|
|
18718
|
+
"next.config.js",
|
|
18719
|
+
"next.config.mjs",
|
|
18720
|
+
"webpack.config.js",
|
|
18721
|
+
"rollup.config.js",
|
|
18722
|
+
"turbo.json",
|
|
18723
|
+
"nx.json",
|
|
18724
|
+
"jest.config.js",
|
|
18725
|
+
"vitest.config.ts",
|
|
18726
|
+
"playwright.config.ts",
|
|
18727
|
+
".env.example",
|
|
18728
|
+
"docker-compose.yml",
|
|
18729
|
+
"Dockerfile"
|
|
18730
|
+
];
|
|
18731
|
+
var PrimerAnalyzer = class {
|
|
18732
|
+
projectPath;
|
|
18733
|
+
packageJson = null;
|
|
18734
|
+
files = /* @__PURE__ */ new Set();
|
|
18735
|
+
constructor(projectPath) {
|
|
18736
|
+
this.projectPath = projectPath;
|
|
18737
|
+
}
|
|
18738
|
+
analyze() {
|
|
18739
|
+
this.loadPackageJson();
|
|
18740
|
+
this.scanFiles();
|
|
18741
|
+
const detector = new ProjectDetector(this.projectPath);
|
|
18742
|
+
const stack = detector.analyze();
|
|
18743
|
+
const patterns = detector.detectPatterns();
|
|
18744
|
+
const analysis = {
|
|
18745
|
+
project: this.getProjectInfo(),
|
|
18746
|
+
languages: this.detectLanguages(),
|
|
18747
|
+
packageManagers: this.detectPackageManagers(),
|
|
18748
|
+
stack,
|
|
18749
|
+
patterns,
|
|
18750
|
+
structure: this.detectProjectStructure(),
|
|
18751
|
+
conventions: this.detectCodeConventions(),
|
|
18752
|
+
ci: this.detectCIConfig(),
|
|
18753
|
+
env: this.detectEnvConfig(),
|
|
18754
|
+
docker: this.detectDockerConfig(),
|
|
18755
|
+
buildCommands: this.extractBuildCommands(),
|
|
18756
|
+
importantFiles: this.findImportantFiles(),
|
|
18757
|
+
codebaseSize: this.estimateCodebaseSize()
|
|
18758
|
+
};
|
|
18759
|
+
return analysis;
|
|
18760
|
+
}
|
|
18761
|
+
loadPackageJson() {
|
|
18762
|
+
const packageJsonPath = join36(this.projectPath, "package.json");
|
|
18763
|
+
if (existsSync35(packageJsonPath)) {
|
|
18764
|
+
try {
|
|
18765
|
+
const content = readFileSync27(packageJsonPath, "utf-8");
|
|
18766
|
+
this.packageJson = JSON.parse(content);
|
|
18767
|
+
} catch {
|
|
18768
|
+
this.packageJson = null;
|
|
18769
|
+
}
|
|
18770
|
+
}
|
|
18771
|
+
}
|
|
18772
|
+
scanFiles(maxDepth = 3) {
|
|
18773
|
+
const scan = (dir, depth) => {
|
|
18774
|
+
if (depth > maxDepth) return;
|
|
18775
|
+
try {
|
|
18776
|
+
const entries = readdirSync10(dir, { withFileTypes: true });
|
|
18777
|
+
for (const entry of entries) {
|
|
18778
|
+
const fullPath = join36(dir, entry.name);
|
|
18779
|
+
const relativePath = relative4(this.projectPath, fullPath);
|
|
18780
|
+
if (entry.name.startsWith(".") && entry.name !== ".github" && entry.name !== ".env.example") {
|
|
18781
|
+
if (!entry.isDirectory()) {
|
|
18782
|
+
this.files.add(relativePath);
|
|
18783
|
+
}
|
|
18784
|
+
continue;
|
|
18785
|
+
}
|
|
18786
|
+
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
|
|
18787
|
+
continue;
|
|
18788
|
+
}
|
|
18789
|
+
this.files.add(relativePath);
|
|
18790
|
+
if (entry.isDirectory()) {
|
|
18791
|
+
scan(fullPath, depth + 1);
|
|
18792
|
+
}
|
|
18793
|
+
}
|
|
18794
|
+
} catch {
|
|
18795
|
+
}
|
|
18796
|
+
};
|
|
18797
|
+
scan(this.projectPath, 0);
|
|
18798
|
+
}
|
|
18799
|
+
getProjectInfo() {
|
|
18800
|
+
const info = {
|
|
18801
|
+
name: basename13(this.projectPath)
|
|
18802
|
+
};
|
|
18803
|
+
if (this.packageJson) {
|
|
18804
|
+
if (typeof this.packageJson.name === "string") {
|
|
18805
|
+
info.name = this.packageJson.name;
|
|
18806
|
+
}
|
|
18807
|
+
if (typeof this.packageJson.description === "string") {
|
|
18808
|
+
info.description = this.packageJson.description;
|
|
18809
|
+
}
|
|
18810
|
+
if (typeof this.packageJson.version === "string") {
|
|
18811
|
+
info.version = this.packageJson.version;
|
|
18812
|
+
}
|
|
18813
|
+
if (typeof this.packageJson.license === "string") {
|
|
18814
|
+
info.license = this.packageJson.license;
|
|
18815
|
+
}
|
|
18816
|
+
const repo = this.packageJson.repository;
|
|
18817
|
+
if (typeof repo === "string") {
|
|
18818
|
+
info.repository = repo;
|
|
18819
|
+
} else if (repo && typeof repo === "object" && "url" in repo) {
|
|
18820
|
+
info.repository = String(repo.url);
|
|
18821
|
+
}
|
|
18822
|
+
}
|
|
18823
|
+
const pyprojectPath = join36(this.projectPath, "pyproject.toml");
|
|
18824
|
+
if (!this.packageJson && existsSync35(pyprojectPath)) {
|
|
18825
|
+
try {
|
|
18826
|
+
const content = readFileSync27(pyprojectPath, "utf-8");
|
|
18827
|
+
const nameMatch = content.match(/name\s*=\s*["']([^"']+)["']/);
|
|
18828
|
+
const versionMatch = content.match(/version\s*=\s*["']([^"']+)["']/);
|
|
18829
|
+
const descMatch = content.match(/description\s*=\s*["']([^"']+)["']/);
|
|
18830
|
+
if (nameMatch) info.name = nameMatch[1];
|
|
18831
|
+
if (versionMatch) info.version = versionMatch[1];
|
|
18832
|
+
if (descMatch) info.description = descMatch[1];
|
|
18833
|
+
} catch {
|
|
18834
|
+
}
|
|
18835
|
+
}
|
|
18836
|
+
const cargoPath = join36(this.projectPath, "Cargo.toml");
|
|
18837
|
+
if (!this.packageJson && existsSync35(cargoPath)) {
|
|
18838
|
+
try {
|
|
18839
|
+
const content = readFileSync27(cargoPath, "utf-8");
|
|
18840
|
+
const nameMatch = content.match(/name\s*=\s*["']([^"']+)["']/);
|
|
18841
|
+
const versionMatch = content.match(/version\s*=\s*["']([^"']+)["']/);
|
|
18842
|
+
const descMatch = content.match(/description\s*=\s*["']([^"']+)["']/);
|
|
18843
|
+
if (nameMatch) info.name = nameMatch[1];
|
|
18844
|
+
if (versionMatch) info.version = versionMatch[1];
|
|
18845
|
+
if (descMatch) info.description = descMatch[1];
|
|
18846
|
+
} catch {
|
|
18847
|
+
}
|
|
18848
|
+
}
|
|
18849
|
+
const detector = new ProjectDetector(this.projectPath);
|
|
18850
|
+
info.type = detector.detectProjectType();
|
|
18851
|
+
return info;
|
|
18852
|
+
}
|
|
18853
|
+
detectLanguages() {
|
|
18854
|
+
const languages = [];
|
|
18855
|
+
if (this.hasFile("tsconfig.json")) {
|
|
18856
|
+
const version = this.getDepVersion("typescript");
|
|
18857
|
+
languages.push({
|
|
18858
|
+
name: "typescript",
|
|
18859
|
+
version,
|
|
18860
|
+
confidence: 100,
|
|
18861
|
+
source: "tsconfig.json"
|
|
18862
|
+
});
|
|
18863
|
+
}
|
|
18864
|
+
if (this.packageJson && !this.hasFile("tsconfig.json")) {
|
|
18865
|
+
languages.push({
|
|
18866
|
+
name: "javascript",
|
|
18867
|
+
confidence: 90,
|
|
18868
|
+
source: "package.json"
|
|
18869
|
+
});
|
|
18870
|
+
}
|
|
18871
|
+
if (this.hasFile("pyproject.toml") || this.hasFile("requirements.txt") || this.hasFile("setup.py")) {
|
|
18872
|
+
const source = this.hasFile("pyproject.toml") ? "pyproject.toml" : this.hasFile("requirements.txt") ? "requirements.txt" : "setup.py";
|
|
18873
|
+
languages.push({
|
|
18874
|
+
name: "python",
|
|
18875
|
+
confidence: 100,
|
|
18876
|
+
source
|
|
18877
|
+
});
|
|
18878
|
+
}
|
|
18879
|
+
if (this.hasFile("go.mod")) {
|
|
18880
|
+
languages.push({
|
|
18881
|
+
name: "go",
|
|
18882
|
+
confidence: 100,
|
|
18883
|
+
source: "go.mod"
|
|
18884
|
+
});
|
|
18885
|
+
}
|
|
18886
|
+
if (this.hasFile("Cargo.toml")) {
|
|
18887
|
+
languages.push({
|
|
18888
|
+
name: "rust",
|
|
18889
|
+
confidence: 100,
|
|
18890
|
+
source: "Cargo.toml"
|
|
18891
|
+
});
|
|
18892
|
+
}
|
|
18893
|
+
if (this.hasFile("pom.xml") || this.hasFile("build.gradle") || this.hasFile("build.gradle.kts")) {
|
|
18894
|
+
languages.push({
|
|
18895
|
+
name: "java",
|
|
18896
|
+
confidence: 100,
|
|
18897
|
+
source: "pom.xml"
|
|
18898
|
+
});
|
|
18899
|
+
}
|
|
18900
|
+
if (this.hasFile("Package.swift")) {
|
|
18901
|
+
languages.push({
|
|
18902
|
+
name: "swift",
|
|
18903
|
+
confidence: 100,
|
|
18904
|
+
source: "Package.swift"
|
|
18905
|
+
});
|
|
18906
|
+
}
|
|
18907
|
+
if (this.hasFile("Gemfile")) {
|
|
18908
|
+
languages.push({
|
|
18909
|
+
name: "ruby",
|
|
18910
|
+
confidence: 100,
|
|
18911
|
+
source: "Gemfile"
|
|
18912
|
+
});
|
|
18913
|
+
}
|
|
18914
|
+
if (this.hasFile("composer.json")) {
|
|
18915
|
+
languages.push({
|
|
18916
|
+
name: "php",
|
|
18917
|
+
confidence: 100,
|
|
18918
|
+
source: "composer.json"
|
|
18919
|
+
});
|
|
18920
|
+
}
|
|
18921
|
+
return languages;
|
|
18922
|
+
}
|
|
18923
|
+
detectPackageManagers() {
|
|
18924
|
+
const managers = /* @__PURE__ */ new Set();
|
|
18925
|
+
for (const [file, manager] of Object.entries(PACKAGE_MANAGER_FILES)) {
|
|
18926
|
+
if (this.hasFile(file)) {
|
|
18927
|
+
managers.add(manager);
|
|
18928
|
+
}
|
|
18929
|
+
}
|
|
18930
|
+
if (this.packageJson) {
|
|
18931
|
+
const packageManager = this.packageJson.packageManager;
|
|
18932
|
+
if (typeof packageManager === "string") {
|
|
18933
|
+
const match = packageManager.match(/^(npm|pnpm|yarn|bun)@/);
|
|
18934
|
+
if (match && ["npm", "pnpm", "yarn", "bun"].includes(match[1])) {
|
|
18935
|
+
managers.add(match[1]);
|
|
18936
|
+
}
|
|
18937
|
+
}
|
|
18938
|
+
}
|
|
18939
|
+
return Array.from(managers);
|
|
18940
|
+
}
|
|
18941
|
+
detectProjectStructure() {
|
|
18942
|
+
const structure = {
|
|
18943
|
+
hasWorkspaces: false
|
|
18944
|
+
};
|
|
18945
|
+
if (this.hasFile("packages") || this.hasFile("apps")) {
|
|
18946
|
+
structure.type = "monorepo";
|
|
18947
|
+
} else if (this.hasFile("src")) {
|
|
18948
|
+
structure.type = "src-based";
|
|
18949
|
+
structure.srcDir = "src";
|
|
18950
|
+
} else if (this.hasFile("lib")) {
|
|
18951
|
+
structure.type = "src-based";
|
|
18952
|
+
structure.srcDir = "lib";
|
|
18953
|
+
} else {
|
|
18954
|
+
structure.type = "flat";
|
|
18955
|
+
}
|
|
18956
|
+
if (this.hasFile("tests") || this.hasFile("test") || this.hasFile("__tests__")) {
|
|
18957
|
+
structure.testDir = this.hasFile("tests") ? "tests" : this.hasFile("test") ? "test" : "__tests__";
|
|
18958
|
+
}
|
|
18959
|
+
if (this.hasFile("docs") || this.hasFile("documentation")) {
|
|
18960
|
+
structure.docsDir = this.hasFile("docs") ? "docs" : "documentation";
|
|
18961
|
+
}
|
|
18962
|
+
if (this.packageJson) {
|
|
18963
|
+
const workspaces = this.packageJson.workspaces;
|
|
18964
|
+
if (Array.isArray(workspaces)) {
|
|
18965
|
+
structure.hasWorkspaces = true;
|
|
18966
|
+
structure.workspaces = workspaces.filter((w) => typeof w === "string");
|
|
18967
|
+
structure.type = "monorepo";
|
|
18968
|
+
} else if (workspaces && typeof workspaces === "object" && "packages" in workspaces) {
|
|
18969
|
+
structure.hasWorkspaces = true;
|
|
18970
|
+
structure.workspaces = workspaces.packages || [];
|
|
18971
|
+
structure.type = "monorepo";
|
|
18972
|
+
}
|
|
18973
|
+
}
|
|
18974
|
+
if (this.hasFile("pnpm-workspace.yaml")) {
|
|
18975
|
+
structure.hasWorkspaces = true;
|
|
18976
|
+
structure.type = "monorepo";
|
|
18977
|
+
}
|
|
18978
|
+
if (this.hasFile("turbo.json") || this.hasFile("nx.json")) {
|
|
18979
|
+
structure.type = "monorepo";
|
|
18980
|
+
}
|
|
18981
|
+
return structure;
|
|
18982
|
+
}
|
|
18983
|
+
detectCodeConventions() {
|
|
18984
|
+
const conventions = {};
|
|
18985
|
+
const prettierConfig = this.readConfigFile([
|
|
18986
|
+
".prettierrc",
|
|
18987
|
+
".prettierrc.json",
|
|
18988
|
+
"prettier.config.js"
|
|
18989
|
+
]);
|
|
18990
|
+
const biomeConfig = this.readConfigFile(["biome.json"]);
|
|
18991
|
+
if (prettierConfig) {
|
|
18992
|
+
try {
|
|
18993
|
+
const config = typeof prettierConfig === "string" ? JSON.parse(prettierConfig) : prettierConfig;
|
|
18994
|
+
if ("semi" in config) conventions.semicolons = config.semi;
|
|
18995
|
+
if ("singleQuote" in config) conventions.quotes = config.singleQuote ? "single" : "double";
|
|
18996
|
+
if ("tabWidth" in config) {
|
|
18997
|
+
conventions.indentation = config.useTabs ? "tabs" : `spaces-${config.tabWidth}`;
|
|
18998
|
+
}
|
|
18999
|
+
if ("trailingComma" in config) conventions.trailingCommas = config.trailingComma;
|
|
19000
|
+
if ("printWidth" in config) conventions.maxLineLength = config.printWidth;
|
|
19001
|
+
} catch {
|
|
19002
|
+
}
|
|
19003
|
+
}
|
|
19004
|
+
if (biomeConfig) {
|
|
19005
|
+
try {
|
|
19006
|
+
const config = typeof biomeConfig === "string" ? JSON.parse(biomeConfig) : biomeConfig;
|
|
19007
|
+
const formatter = config.formatter || {};
|
|
19008
|
+
const js = config.javascript?.formatter || {};
|
|
19009
|
+
if (formatter.indentStyle) conventions.indentation = formatter.indentStyle === "tab" ? "tabs" : "spaces-2";
|
|
19010
|
+
if (formatter.lineWidth) conventions.maxLineLength = formatter.lineWidth;
|
|
19011
|
+
if (js.quoteStyle) conventions.quotes = js.quoteStyle;
|
|
19012
|
+
if (js.semicolons) conventions.semicolons = js.semicolons !== "asNeeded";
|
|
19013
|
+
if (js.trailingCommas) conventions.trailingCommas = js.trailingCommas;
|
|
19014
|
+
} catch {
|
|
19015
|
+
}
|
|
19016
|
+
}
|
|
19017
|
+
if (this.hasFile("tsconfig.json")) {
|
|
19018
|
+
try {
|
|
19019
|
+
const tsconfigPath = join36(this.projectPath, "tsconfig.json");
|
|
19020
|
+
const content = readFileSync27(tsconfigPath, "utf-8");
|
|
19021
|
+
const tsconfig = JSON.parse(content.replace(/\/\/.*$/gm, "").replace(/,\s*}/g, "}"));
|
|
19022
|
+
const paths = tsconfig.compilerOptions?.paths;
|
|
19023
|
+
if (paths && Object.keys(paths).some((k) => k.startsWith("@"))) {
|
|
19024
|
+
conventions.namingStyle = "camelCase";
|
|
19025
|
+
}
|
|
19026
|
+
} catch {
|
|
19027
|
+
}
|
|
19028
|
+
}
|
|
19029
|
+
return conventions;
|
|
19030
|
+
}
|
|
19031
|
+
detectCIConfig() {
|
|
19032
|
+
const ci = {
|
|
19033
|
+
hasCI: false,
|
|
19034
|
+
hasCD: false
|
|
19035
|
+
};
|
|
19036
|
+
for (const [file, provider] of Object.entries(CI_CONFIG_FILES)) {
|
|
19037
|
+
if (this.hasFile(file)) {
|
|
19038
|
+
ci.hasCI = true;
|
|
19039
|
+
ci.provider = provider;
|
|
19040
|
+
ci.configFile = file;
|
|
19041
|
+
break;
|
|
19042
|
+
}
|
|
19043
|
+
}
|
|
19044
|
+
if (this.hasFile(".github/workflows")) {
|
|
19045
|
+
ci.hasCI = true;
|
|
19046
|
+
ci.provider = "github-actions";
|
|
19047
|
+
ci.configFile = ".github/workflows";
|
|
19048
|
+
try {
|
|
19049
|
+
const workflowsDir = join36(this.projectPath, ".github/workflows");
|
|
19050
|
+
const workflows = readdirSync10(workflowsDir);
|
|
19051
|
+
const deployWorkflows = workflows.filter(
|
|
19052
|
+
(f) => f.includes("deploy") || f.includes("release") || f.includes("publish")
|
|
19053
|
+
);
|
|
19054
|
+
if (deployWorkflows.length > 0) {
|
|
19055
|
+
ci.hasCD = true;
|
|
19056
|
+
}
|
|
19057
|
+
} catch {
|
|
19058
|
+
}
|
|
19059
|
+
}
|
|
19060
|
+
return ci;
|
|
19061
|
+
}
|
|
19062
|
+
detectEnvConfig() {
|
|
19063
|
+
const env = {
|
|
19064
|
+
hasEnvFile: false,
|
|
19065
|
+
hasEnvExample: false
|
|
19066
|
+
};
|
|
19067
|
+
env.hasEnvFile = this.hasFile(".env");
|
|
19068
|
+
env.hasEnvExample = this.hasFile(".env.example") || this.hasFile(".env.template") || this.hasFile(".env.sample");
|
|
19069
|
+
if (env.hasEnvExample) {
|
|
19070
|
+
const envExamplePath = join36(
|
|
19071
|
+
this.projectPath,
|
|
19072
|
+
this.hasFile(".env.example") ? ".env.example" : this.hasFile(".env.template") ? ".env.template" : ".env.sample"
|
|
19073
|
+
);
|
|
19074
|
+
try {
|
|
19075
|
+
const content = readFileSync27(envExamplePath, "utf-8");
|
|
19076
|
+
const variables = content.split("\n").filter((line) => line.trim() && !line.startsWith("#")).map((line) => line.split("=")[0].trim()).filter((v) => v);
|
|
19077
|
+
env.envVariables = variables;
|
|
19078
|
+
} catch {
|
|
19079
|
+
}
|
|
19080
|
+
}
|
|
19081
|
+
return env;
|
|
19082
|
+
}
|
|
19083
|
+
detectDockerConfig() {
|
|
19084
|
+
const docker = {
|
|
19085
|
+
hasDockerfile: false,
|
|
19086
|
+
hasCompose: false
|
|
19087
|
+
};
|
|
19088
|
+
docker.hasDockerfile = this.hasFile("Dockerfile");
|
|
19089
|
+
docker.hasCompose = this.hasFile("docker-compose.yml") || this.hasFile("docker-compose.yaml") || this.hasFile("compose.yml");
|
|
19090
|
+
if (docker.hasDockerfile) {
|
|
19091
|
+
try {
|
|
19092
|
+
const dockerfilePath = join36(this.projectPath, "Dockerfile");
|
|
19093
|
+
const content = readFileSync27(dockerfilePath, "utf-8");
|
|
19094
|
+
const fromMatch = content.match(/^FROM\s+(\S+)/m);
|
|
19095
|
+
if (fromMatch) {
|
|
19096
|
+
docker.baseImage = fromMatch[1];
|
|
19097
|
+
}
|
|
19098
|
+
} catch {
|
|
19099
|
+
}
|
|
19100
|
+
}
|
|
19101
|
+
return docker;
|
|
19102
|
+
}
|
|
19103
|
+
extractBuildCommands() {
|
|
19104
|
+
const commands = {};
|
|
19105
|
+
if (this.packageJson && this.packageJson.scripts) {
|
|
19106
|
+
const scripts = this.packageJson.scripts;
|
|
19107
|
+
if (scripts.build) commands.build = this.getRunCommand("build");
|
|
19108
|
+
if (scripts.test) commands.test = this.getRunCommand("test");
|
|
19109
|
+
if (scripts.lint) commands.lint = this.getRunCommand("lint");
|
|
19110
|
+
if (scripts.format) commands.format = this.getRunCommand("format");
|
|
19111
|
+
if (scripts.dev) commands.dev = this.getRunCommand("dev");
|
|
19112
|
+
if (scripts.start) commands.start = this.getRunCommand("start");
|
|
19113
|
+
}
|
|
19114
|
+
const packageManagers = this.detectPackageManagers();
|
|
19115
|
+
if (!commands.install) {
|
|
19116
|
+
if (packageManagers.includes("pnpm")) {
|
|
19117
|
+
commands.install = "pnpm install";
|
|
19118
|
+
} else if (packageManagers.includes("yarn")) {
|
|
19119
|
+
commands.install = "yarn install";
|
|
19120
|
+
} else if (packageManagers.includes("bun")) {
|
|
19121
|
+
commands.install = "bun install";
|
|
19122
|
+
} else if (packageManagers.includes("npm")) {
|
|
19123
|
+
commands.install = "npm install";
|
|
19124
|
+
} else if (packageManagers.includes("pip") || packageManagers.includes("poetry") || packageManagers.includes("uv")) {
|
|
19125
|
+
if (packageManagers.includes("poetry")) {
|
|
19126
|
+
commands.install = "poetry install";
|
|
19127
|
+
} else if (packageManagers.includes("uv")) {
|
|
19128
|
+
commands.install = "uv sync";
|
|
19129
|
+
} else {
|
|
19130
|
+
commands.install = "pip install -r requirements.txt";
|
|
19131
|
+
}
|
|
19132
|
+
} else if (packageManagers.includes("cargo")) {
|
|
19133
|
+
commands.install = "cargo build";
|
|
19134
|
+
} else if (packageManagers.includes("go")) {
|
|
19135
|
+
commands.install = "go mod download";
|
|
19136
|
+
}
|
|
19137
|
+
}
|
|
19138
|
+
return commands;
|
|
19139
|
+
}
|
|
19140
|
+
findImportantFiles() {
|
|
19141
|
+
const important = [];
|
|
19142
|
+
for (const file of IMPORTANT_CONFIG_FILES) {
|
|
19143
|
+
if (this.hasFile(file)) {
|
|
19144
|
+
important.push(file);
|
|
19145
|
+
}
|
|
19146
|
+
}
|
|
19147
|
+
if (this.hasFile("README.md")) {
|
|
19148
|
+
important.push("README.md");
|
|
19149
|
+
}
|
|
19150
|
+
if (this.hasFile("CONTRIBUTING.md")) {
|
|
19151
|
+
important.push("CONTRIBUTING.md");
|
|
19152
|
+
}
|
|
19153
|
+
if (this.hasFile("LICENSE") || this.hasFile("LICENSE.md")) {
|
|
19154
|
+
important.push(this.hasFile("LICENSE") ? "LICENSE" : "LICENSE.md");
|
|
19155
|
+
}
|
|
19156
|
+
return important;
|
|
19157
|
+
}
|
|
19158
|
+
estimateCodebaseSize() {
|
|
19159
|
+
let files = 0;
|
|
19160
|
+
let directories = 0;
|
|
19161
|
+
for (const file of this.files) {
|
|
19162
|
+
if (file.includes(sep2)) {
|
|
19163
|
+
directories++;
|
|
19164
|
+
}
|
|
19165
|
+
files++;
|
|
19166
|
+
}
|
|
19167
|
+
return {
|
|
19168
|
+
files,
|
|
19169
|
+
directories: Math.floor(directories / 3)
|
|
19170
|
+
};
|
|
19171
|
+
}
|
|
19172
|
+
hasFile(name) {
|
|
19173
|
+
if (name.includes("*")) {
|
|
19174
|
+
const regex = new RegExp(
|
|
19175
|
+
name.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")
|
|
19176
|
+
);
|
|
19177
|
+
for (const file of this.files) {
|
|
19178
|
+
if (regex.test(file)) return true;
|
|
19179
|
+
}
|
|
19180
|
+
return false;
|
|
19181
|
+
}
|
|
19182
|
+
return this.files.has(name) || existsSync35(join36(this.projectPath, name));
|
|
19183
|
+
}
|
|
19184
|
+
getDepVersion(dep) {
|
|
19185
|
+
if (!this.packageJson) return void 0;
|
|
19186
|
+
const deps = this.packageJson.dependencies;
|
|
19187
|
+
const devDeps = this.packageJson.devDependencies;
|
|
19188
|
+
const version = deps?.[dep] || devDeps?.[dep];
|
|
19189
|
+
return version?.replace(/^[\^~>=<]+/, "");
|
|
19190
|
+
}
|
|
19191
|
+
getRunCommand(script) {
|
|
19192
|
+
const packageManagers = this.detectPackageManagers();
|
|
19193
|
+
if (packageManagers.includes("pnpm")) {
|
|
19194
|
+
return `pnpm ${script}`;
|
|
19195
|
+
} else if (packageManagers.includes("yarn")) {
|
|
19196
|
+
return `yarn ${script}`;
|
|
19197
|
+
} else if (packageManagers.includes("bun")) {
|
|
19198
|
+
return `bun run ${script}`;
|
|
19199
|
+
}
|
|
19200
|
+
return `npm run ${script}`;
|
|
19201
|
+
}
|
|
19202
|
+
readConfigFile(files) {
|
|
19203
|
+
for (const file of files) {
|
|
19204
|
+
const filePath = join36(this.projectPath, file);
|
|
19205
|
+
if (existsSync35(filePath)) {
|
|
19206
|
+
try {
|
|
19207
|
+
const content = readFileSync27(filePath, "utf-8");
|
|
19208
|
+
if (file.endsWith(".json")) {
|
|
19209
|
+
return JSON.parse(content);
|
|
19210
|
+
}
|
|
19211
|
+
return content;
|
|
19212
|
+
} catch {
|
|
19213
|
+
}
|
|
19214
|
+
}
|
|
19215
|
+
}
|
|
19216
|
+
return null;
|
|
19217
|
+
}
|
|
19218
|
+
};
|
|
19219
|
+
function analyzePrimer(projectPath) {
|
|
19220
|
+
const analyzer = new PrimerAnalyzer(projectPath);
|
|
19221
|
+
return analyzer.analyze();
|
|
19222
|
+
}
|
|
19223
|
+
|
|
19224
|
+
// src/primer/generator.ts
|
|
19225
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync19, writeFileSync as writeFileSync19 } from "fs";
|
|
19226
|
+
import { join as join37, dirname as dirname13 } from "path";
|
|
19227
|
+
var ALL_AGENTS = Object.keys(AGENT_CONFIG);
|
|
19228
|
+
var markdownRenderer = {
|
|
19229
|
+
h1: (text) => `# ${text}`,
|
|
19230
|
+
h2: (text) => `## ${text}`,
|
|
19231
|
+
h3: (text) => `### ${text}`,
|
|
19232
|
+
bold: (text) => `**${text}**`,
|
|
19233
|
+
code: (text) => `\`${text}\``,
|
|
19234
|
+
codeBlock: (code, lang = "") => `\`\`\`${lang}
|
|
19235
|
+
${code}
|
|
19236
|
+
\`\`\``,
|
|
19237
|
+
list: (items) => items.map((item) => `- ${item}`).join("\n"),
|
|
19238
|
+
keyValue: (key, value) => `**${key}:** ${value}`,
|
|
19239
|
+
paragraph: (text) => text,
|
|
19240
|
+
separator: () => "",
|
|
19241
|
+
wrap: (content) => content
|
|
19242
|
+
};
|
|
19243
|
+
var mdcRenderer = {
|
|
19244
|
+
h1: (text) => `# ${text}`,
|
|
19245
|
+
h2: (text) => `## ${text}`,
|
|
19246
|
+
h3: (text) => `### ${text}`,
|
|
19247
|
+
bold: (text) => `**${text}**`,
|
|
19248
|
+
code: (text) => `\`${text}\``,
|
|
19249
|
+
codeBlock: (code, lang = "") => `\`\`\`${lang}
|
|
19250
|
+
${code}
|
|
19251
|
+
\`\`\``,
|
|
19252
|
+
list: (items) => items.map((item) => `- ${item}`).join("\n"),
|
|
19253
|
+
keyValue: (key, value) => `**${key}:** ${value}`,
|
|
19254
|
+
paragraph: (text) => text,
|
|
19255
|
+
separator: () => "",
|
|
19256
|
+
wrap: (content, metadata) => {
|
|
19257
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
19258
|
+
const yaml = Object.entries(metadata).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join("\n");
|
|
19259
|
+
return `---
|
|
19260
|
+
${yaml}
|
|
19261
|
+
---
|
|
19262
|
+
|
|
19263
|
+
${content}`;
|
|
19264
|
+
}
|
|
19265
|
+
return content;
|
|
19266
|
+
}
|
|
19267
|
+
};
|
|
19268
|
+
var jsonRenderer = {
|
|
19269
|
+
h1: (text) => text,
|
|
19270
|
+
h2: (text) => text,
|
|
19271
|
+
h3: (text) => text,
|
|
19272
|
+
bold: (text) => text,
|
|
19273
|
+
code: (text) => text,
|
|
19274
|
+
codeBlock: (code) => code,
|
|
19275
|
+
list: (items) => items.join(", "),
|
|
19276
|
+
keyValue: (key, value) => `${key}: ${value}`,
|
|
19277
|
+
paragraph: (text) => text,
|
|
19278
|
+
separator: () => "",
|
|
19279
|
+
wrap: (content, metadata) => {
|
|
19280
|
+
try {
|
|
19281
|
+
const data = { ...metadata, content };
|
|
19282
|
+
return JSON.stringify(data, null, 2);
|
|
19283
|
+
} catch {
|
|
19284
|
+
return content;
|
|
19285
|
+
}
|
|
19286
|
+
}
|
|
19287
|
+
};
|
|
19288
|
+
var xmlRenderer = {
|
|
19289
|
+
h1: (text) => `<h1>${escapeXml2(text)}</h1>`,
|
|
19290
|
+
h2: (text) => `<h2>${escapeXml2(text)}</h2>`,
|
|
19291
|
+
h3: (text) => `<h3>${escapeXml2(text)}</h3>`,
|
|
19292
|
+
bold: (text) => `<strong>${escapeXml2(text)}</strong>`,
|
|
19293
|
+
code: (text) => `<code>${escapeXml2(text)}</code>`,
|
|
19294
|
+
codeBlock: (code, lang = "") => `<pre${lang ? ` lang="${lang}"` : ""}><code>${escapeXml2(code)}</code></pre>`,
|
|
19295
|
+
list: (items) => `<ul>
|
|
19296
|
+
${items.map((item) => ` <li>${escapeXml2(item)}</li>`).join("\n")}
|
|
19297
|
+
</ul>`,
|
|
19298
|
+
keyValue: (key, value) => `<dt>${escapeXml2(key)}</dt><dd>${escapeXml2(value)}</dd>`,
|
|
19299
|
+
paragraph: (text) => `<p>${escapeXml2(text)}</p>`,
|
|
19300
|
+
separator: () => "",
|
|
19301
|
+
wrap: (content, metadata) => {
|
|
19302
|
+
const attrs = metadata ? Object.entries(metadata).map(([k, v]) => `${k}="${escapeXml2(String(v))}"`).join(" ") : "";
|
|
19303
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
19304
|
+
<instructions${attrs ? " " + attrs : ""}>
|
|
19305
|
+
${content}
|
|
19306
|
+
</instructions>`;
|
|
19307
|
+
}
|
|
19308
|
+
};
|
|
19309
|
+
function escapeXml2(text) {
|
|
19310
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
19311
|
+
}
|
|
19312
|
+
function getRenderer(format) {
|
|
19313
|
+
switch (format) {
|
|
19314
|
+
case "mdc":
|
|
19315
|
+
return mdcRenderer;
|
|
19316
|
+
case "json":
|
|
19317
|
+
return jsonRenderer;
|
|
19318
|
+
case "xml":
|
|
19319
|
+
return xmlRenderer;
|
|
19320
|
+
default:
|
|
19321
|
+
return markdownRenderer;
|
|
19322
|
+
}
|
|
19323
|
+
}
|
|
19324
|
+
var PrimerGenerator = class {
|
|
19325
|
+
projectPath;
|
|
19326
|
+
options;
|
|
19327
|
+
analysis = null;
|
|
19328
|
+
constructor(projectPath, options = {}) {
|
|
19329
|
+
this.projectPath = projectPath;
|
|
19330
|
+
this.options = options;
|
|
19331
|
+
}
|
|
19332
|
+
generate() {
|
|
19333
|
+
const warnings = [];
|
|
19334
|
+
const errors = [];
|
|
19335
|
+
const generated = [];
|
|
19336
|
+
const seenPaths = /* @__PURE__ */ new Map();
|
|
19337
|
+
this.analysis = analyzePrimer(this.projectPath);
|
|
19338
|
+
if (this.options.analyzeOnly) {
|
|
19339
|
+
return {
|
|
19340
|
+
success: true,
|
|
19341
|
+
analysis: this.analysis,
|
|
19342
|
+
generated: [],
|
|
19343
|
+
warnings,
|
|
19344
|
+
errors
|
|
19345
|
+
};
|
|
19346
|
+
}
|
|
19347
|
+
const targetAgents = this.getTargetAgents();
|
|
19348
|
+
for (const agent of targetAgents) {
|
|
19349
|
+
try {
|
|
19350
|
+
const instruction = this.generateForAgent(agent);
|
|
19351
|
+
if (instruction) {
|
|
19352
|
+
const existingAgent = seenPaths.get(instruction.filepath);
|
|
19353
|
+
if (existingAgent) {
|
|
19354
|
+
warnings.push(
|
|
19355
|
+
`Skipping ${agent}: output path "${instruction.filename}" already used by ${existingAgent}`
|
|
19356
|
+
);
|
|
19357
|
+
continue;
|
|
19358
|
+
}
|
|
19359
|
+
seenPaths.set(instruction.filepath, agent);
|
|
19360
|
+
if (!this.options.dryRun) {
|
|
19361
|
+
this.writeInstruction(instruction);
|
|
19362
|
+
}
|
|
19363
|
+
generated.push(instruction);
|
|
19364
|
+
}
|
|
19365
|
+
} catch (error) {
|
|
19366
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19367
|
+
errors.push(`Failed to generate for ${agent}: ${message}`);
|
|
19368
|
+
}
|
|
19369
|
+
}
|
|
19370
|
+
return {
|
|
19371
|
+
success: errors.length === 0,
|
|
19372
|
+
analysis: this.analysis,
|
|
19373
|
+
generated,
|
|
19374
|
+
warnings,
|
|
19375
|
+
errors
|
|
19376
|
+
};
|
|
19377
|
+
}
|
|
19378
|
+
getTargetAgents() {
|
|
19379
|
+
if (this.options.allAgents) {
|
|
19380
|
+
return ALL_AGENTS;
|
|
19381
|
+
}
|
|
19382
|
+
if (this.options.agents && this.options.agents.length > 0) {
|
|
19383
|
+
return this.options.agents;
|
|
19384
|
+
}
|
|
19385
|
+
return this.detectInstalledAgents();
|
|
19386
|
+
}
|
|
19387
|
+
detectInstalledAgents() {
|
|
19388
|
+
const detected = [];
|
|
19389
|
+
for (const [agent, config] of Object.entries(AGENT_CONFIG)) {
|
|
19390
|
+
const configPath = join37(this.projectPath, config.configFile);
|
|
19391
|
+
const skillsPath = join37(this.projectPath, config.skillsDir);
|
|
19392
|
+
if (existsSync36(configPath) || existsSync36(skillsPath)) {
|
|
19393
|
+
detected.push(agent);
|
|
19394
|
+
}
|
|
19395
|
+
if (config.altSkillsDirs) {
|
|
19396
|
+
for (const altDir of config.altSkillsDirs) {
|
|
19397
|
+
if (existsSync36(join37(this.projectPath, altDir))) {
|
|
19398
|
+
if (!detected.includes(agent)) {
|
|
19399
|
+
detected.push(agent);
|
|
19400
|
+
}
|
|
19401
|
+
break;
|
|
19402
|
+
}
|
|
19403
|
+
}
|
|
19404
|
+
}
|
|
19405
|
+
}
|
|
19406
|
+
if (detected.length === 0) {
|
|
19407
|
+
detected.push("claude-code", "cursor", "github-copilot");
|
|
19408
|
+
}
|
|
19409
|
+
return detected;
|
|
19410
|
+
}
|
|
19411
|
+
generateForAgent(agent) {
|
|
19412
|
+
if (!this.analysis) return null;
|
|
19413
|
+
const config = AGENT_CONFIG[agent];
|
|
19414
|
+
const template = AGENT_INSTRUCTION_TEMPLATES[agent] || this.getDefaultTemplate(agent, config);
|
|
19415
|
+
const content = this.generateContent(template);
|
|
19416
|
+
const outputDir = this.options.outputDir || this.projectPath;
|
|
19417
|
+
const filepath = join37(outputDir, template.filename);
|
|
19418
|
+
return {
|
|
19419
|
+
agent,
|
|
19420
|
+
filename: template.filename,
|
|
19421
|
+
filepath,
|
|
19422
|
+
content,
|
|
19423
|
+
format: template.format
|
|
19424
|
+
};
|
|
19425
|
+
}
|
|
19426
|
+
getDefaultTemplate(agent, config) {
|
|
19427
|
+
const formatMap = {
|
|
19428
|
+
".md": "markdown",
|
|
19429
|
+
".json": "json",
|
|
19430
|
+
".mdc": "mdc",
|
|
19431
|
+
".xml": "xml"
|
|
19432
|
+
};
|
|
19433
|
+
const ext = config.configFile.includes(".") ? "." + config.configFile.split(".").pop() : ".md";
|
|
19434
|
+
const format = formatMap[ext] || "markdown";
|
|
19435
|
+
return {
|
|
19436
|
+
agent,
|
|
19437
|
+
filename: config.configFile,
|
|
19438
|
+
format,
|
|
19439
|
+
sectionOrder: ["overview", "stack", "commands", "conventions", "structure", "guidelines"]
|
|
19440
|
+
};
|
|
19441
|
+
}
|
|
19442
|
+
generateContent(template) {
|
|
19443
|
+
if (!this.analysis) return "";
|
|
19444
|
+
const format = template.format;
|
|
19445
|
+
const renderer = getRenderer(format);
|
|
19446
|
+
if (format === "json") {
|
|
19447
|
+
return this.generateJsonContent(template);
|
|
19448
|
+
}
|
|
19449
|
+
const sections = [];
|
|
19450
|
+
for (const section of template.sectionOrder) {
|
|
19451
|
+
const content = this.generateSection(section, template, renderer);
|
|
19452
|
+
if (content) {
|
|
19453
|
+
sections.push(content);
|
|
19454
|
+
}
|
|
19455
|
+
}
|
|
19456
|
+
let result = sections.join("\n\n");
|
|
19457
|
+
if (template.header) {
|
|
19458
|
+
result = template.header + "\n\n" + result;
|
|
19459
|
+
}
|
|
19460
|
+
if (template.footer) {
|
|
19461
|
+
result = result + "\n\n" + template.footer;
|
|
19462
|
+
}
|
|
19463
|
+
if (this.options.customInstructions) {
|
|
19464
|
+
result += "\n\n" + renderer.h2("Custom Instructions") + "\n\n" + this.options.customInstructions;
|
|
19465
|
+
}
|
|
19466
|
+
const metadata = format === "mdc" ? {
|
|
19467
|
+
title: this.analysis.project.name,
|
|
19468
|
+
type: this.analysis.project.type,
|
|
19469
|
+
generated: (/* @__PURE__ */ new Date()).toISOString()
|
|
19470
|
+
} : void 0;
|
|
19471
|
+
return renderer.wrap(result, metadata);
|
|
19472
|
+
}
|
|
19473
|
+
generateJsonContent(template) {
|
|
19474
|
+
if (!this.analysis) return "{}";
|
|
19475
|
+
const data = {
|
|
19476
|
+
project: this.analysis.project,
|
|
19477
|
+
languages: this.analysis.languages.map((l) => l.name),
|
|
19478
|
+
packageManagers: this.analysis.packageManagers,
|
|
19479
|
+
stack: {
|
|
19480
|
+
frameworks: this.analysis.stack.frameworks.map((f) => ({ name: f.name, version: f.version })),
|
|
19481
|
+
libraries: this.analysis.stack.libraries.map((l) => ({ name: l.name, version: l.version })),
|
|
19482
|
+
styling: this.analysis.stack.styling.map((s) => s.name),
|
|
19483
|
+
testing: this.analysis.stack.testing.map((t) => t.name),
|
|
19484
|
+
databases: this.analysis.stack.databases.map((d) => d.name)
|
|
19485
|
+
},
|
|
19486
|
+
commands: this.analysis.buildCommands,
|
|
19487
|
+
conventions: this.analysis.conventions,
|
|
19488
|
+
structure: this.analysis.structure,
|
|
19489
|
+
importantFiles: this.analysis.importantFiles,
|
|
19490
|
+
generated: {
|
|
19491
|
+
agent: template.agent,
|
|
19492
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
19493
|
+
}
|
|
19494
|
+
};
|
|
19495
|
+
if (this.options.customInstructions) {
|
|
19496
|
+
data.customInstructions = this.options.customInstructions;
|
|
19497
|
+
}
|
|
19498
|
+
return JSON.stringify(data, null, 2);
|
|
19499
|
+
}
|
|
19500
|
+
generateSection(section, template, renderer) {
|
|
19501
|
+
if (!this.analysis) return "";
|
|
19502
|
+
switch (section) {
|
|
19503
|
+
case "overview":
|
|
19504
|
+
return this.generateOverviewSection(renderer);
|
|
19505
|
+
case "stack":
|
|
19506
|
+
return this.generateStackSection(renderer);
|
|
19507
|
+
case "commands":
|
|
19508
|
+
return this.generateCommandsSection(renderer);
|
|
19509
|
+
case "conventions":
|
|
19510
|
+
return this.generateConventionsSection(renderer);
|
|
19511
|
+
case "structure":
|
|
19512
|
+
return this.generateStructureSection(renderer);
|
|
19513
|
+
case "guidelines":
|
|
19514
|
+
return this.generateGuidelinesSection(template.agent, renderer);
|
|
19515
|
+
default:
|
|
19516
|
+
return "";
|
|
19517
|
+
}
|
|
19518
|
+
}
|
|
19519
|
+
generateOverviewSection(renderer) {
|
|
19520
|
+
if (!this.analysis) return "";
|
|
19521
|
+
const { project, languages } = this.analysis;
|
|
19522
|
+
const lines = [];
|
|
19523
|
+
lines.push(renderer.h1(project.name));
|
|
19524
|
+
lines.push("");
|
|
19525
|
+
if (project.description) {
|
|
19526
|
+
lines.push(renderer.paragraph(project.description));
|
|
19527
|
+
lines.push("");
|
|
19528
|
+
}
|
|
19529
|
+
if (project.type) {
|
|
19530
|
+
lines.push(renderer.keyValue("Project Type", this.formatProjectType(project.type)));
|
|
19531
|
+
}
|
|
19532
|
+
if (languages.length > 0) {
|
|
19533
|
+
const langNames = languages.map((l) => this.capitalize(l.name)).join(", ");
|
|
19534
|
+
lines.push(renderer.keyValue("Languages", langNames));
|
|
19535
|
+
}
|
|
19536
|
+
if (project.version) {
|
|
19537
|
+
lines.push(renderer.keyValue("Version", project.version));
|
|
19538
|
+
}
|
|
19539
|
+
return lines.join("\n");
|
|
19540
|
+
}
|
|
19541
|
+
generateStackSection(renderer) {
|
|
19542
|
+
if (!this.analysis) return "";
|
|
19543
|
+
const { stack, packageManagers } = this.analysis;
|
|
19544
|
+
const lines = [];
|
|
19545
|
+
lines.push(renderer.h2("Technology Stack"));
|
|
19546
|
+
lines.push("");
|
|
19547
|
+
if (stack.frameworks.length > 0) {
|
|
19548
|
+
lines.push(renderer.h3("Frameworks"));
|
|
19549
|
+
const items = stack.frameworks.map((fw) => {
|
|
19550
|
+
const version = fw.version ? ` (${fw.version})` : "";
|
|
19551
|
+
return `${this.capitalize(fw.name)}${version}`;
|
|
19552
|
+
});
|
|
19553
|
+
lines.push(renderer.list(items));
|
|
19554
|
+
lines.push("");
|
|
19555
|
+
}
|
|
19556
|
+
if (stack.libraries.length > 0) {
|
|
19557
|
+
lines.push(renderer.h3("Libraries"));
|
|
19558
|
+
const items = stack.libraries.map((lib) => {
|
|
19559
|
+
const version = lib.version ? ` (${lib.version})` : "";
|
|
19560
|
+
return `${this.capitalize(lib.name)}${version}`;
|
|
19561
|
+
});
|
|
19562
|
+
lines.push(renderer.list(items));
|
|
19563
|
+
lines.push("");
|
|
19564
|
+
}
|
|
19565
|
+
if (stack.styling.length > 0) {
|
|
19566
|
+
lines.push(renderer.h3("Styling"));
|
|
19567
|
+
lines.push(renderer.list(stack.styling.map((s) => this.capitalize(s.name))));
|
|
19568
|
+
lines.push("");
|
|
19569
|
+
}
|
|
19570
|
+
if (stack.testing.length > 0) {
|
|
19571
|
+
lines.push(renderer.h3("Testing"));
|
|
19572
|
+
lines.push(renderer.list(stack.testing.map((t) => this.capitalize(t.name))));
|
|
19573
|
+
lines.push("");
|
|
19574
|
+
}
|
|
19575
|
+
if (stack.databases.length > 0) {
|
|
19576
|
+
lines.push(renderer.h3("Databases"));
|
|
19577
|
+
lines.push(renderer.list(stack.databases.map((d) => this.capitalize(d.name))));
|
|
19578
|
+
lines.push("");
|
|
19579
|
+
}
|
|
19580
|
+
if (packageManagers.length > 0) {
|
|
19581
|
+
lines.push(renderer.h3("Package Manager"));
|
|
19582
|
+
lines.push(renderer.list([packageManagers.map((pm) => this.capitalize(pm)).join(", ")]));
|
|
19583
|
+
lines.push("");
|
|
19584
|
+
}
|
|
19585
|
+
return lines.join("\n");
|
|
19586
|
+
}
|
|
19587
|
+
generateCommandsSection(renderer) {
|
|
19588
|
+
if (!this.analysis || !this.analysis.buildCommands) return "";
|
|
19589
|
+
const { buildCommands } = this.analysis;
|
|
19590
|
+
const lines = [];
|
|
19591
|
+
const commands = [];
|
|
19592
|
+
lines.push(renderer.h2("Development Commands"));
|
|
19593
|
+
lines.push("");
|
|
19594
|
+
if (buildCommands.install) {
|
|
19595
|
+
commands.push(`# Install dependencies`);
|
|
19596
|
+
commands.push(buildCommands.install);
|
|
19597
|
+
commands.push("");
|
|
19598
|
+
}
|
|
19599
|
+
if (buildCommands.dev) {
|
|
19600
|
+
commands.push(`# Start development server`);
|
|
19601
|
+
commands.push(buildCommands.dev);
|
|
19602
|
+
commands.push("");
|
|
19603
|
+
}
|
|
19604
|
+
if (buildCommands.build) {
|
|
19605
|
+
commands.push(`# Build for production`);
|
|
19606
|
+
commands.push(buildCommands.build);
|
|
19607
|
+
commands.push("");
|
|
19608
|
+
}
|
|
19609
|
+
if (buildCommands.test) {
|
|
19610
|
+
commands.push(`# Run tests`);
|
|
19611
|
+
commands.push(buildCommands.test);
|
|
19612
|
+
commands.push("");
|
|
19613
|
+
}
|
|
19614
|
+
if (buildCommands.lint) {
|
|
19615
|
+
commands.push(`# Run linter`);
|
|
19616
|
+
commands.push(buildCommands.lint);
|
|
19617
|
+
commands.push("");
|
|
19618
|
+
}
|
|
19619
|
+
if (buildCommands.format) {
|
|
19620
|
+
commands.push(`# Format code`);
|
|
19621
|
+
commands.push(buildCommands.format);
|
|
19622
|
+
}
|
|
19623
|
+
lines.push(renderer.codeBlock(commands.join("\n"), "bash"));
|
|
19624
|
+
return lines.join("\n");
|
|
19625
|
+
}
|
|
19626
|
+
generateConventionsSection(renderer) {
|
|
19627
|
+
if (!this.analysis) return "";
|
|
19628
|
+
const { conventions, patterns } = this.analysis;
|
|
19629
|
+
const lines = [];
|
|
19630
|
+
lines.push(renderer.h2("Code Conventions"));
|
|
19631
|
+
lines.push("");
|
|
19632
|
+
if (conventions) {
|
|
19633
|
+
const items = [];
|
|
19634
|
+
if (conventions.indentation) {
|
|
19635
|
+
items.push(`${renderer.bold("Indentation:")} ${conventions.indentation}`);
|
|
19636
|
+
}
|
|
19637
|
+
if (conventions.quotes) {
|
|
19638
|
+
items.push(`${renderer.bold("Quotes:")} ${conventions.quotes}`);
|
|
19639
|
+
}
|
|
19640
|
+
if (conventions.semicolons !== void 0) {
|
|
19641
|
+
items.push(`${renderer.bold("Semicolons:")} ${conventions.semicolons ? "required" : "omitted"}`);
|
|
19642
|
+
}
|
|
19643
|
+
if (conventions.trailingCommas) {
|
|
19644
|
+
items.push(`${renderer.bold("Trailing Commas:")} ${conventions.trailingCommas}`);
|
|
19645
|
+
}
|
|
19646
|
+
if (conventions.maxLineLength) {
|
|
19647
|
+
items.push(`${renderer.bold("Max Line Length:")} ${conventions.maxLineLength}`);
|
|
19648
|
+
}
|
|
19649
|
+
if (items.length > 0) {
|
|
19650
|
+
lines.push(renderer.list(items));
|
|
19651
|
+
}
|
|
19652
|
+
}
|
|
19653
|
+
if (patterns) {
|
|
19654
|
+
lines.push("");
|
|
19655
|
+
lines.push(renderer.h3("Patterns"));
|
|
19656
|
+
const items = [];
|
|
19657
|
+
if (patterns.components) {
|
|
19658
|
+
items.push(`${renderer.bold("Components:")} ${patterns.components}`);
|
|
19659
|
+
}
|
|
19660
|
+
if (patterns.stateManagement) {
|
|
19661
|
+
items.push(`${renderer.bold("State Management:")} ${patterns.stateManagement}`);
|
|
19662
|
+
}
|
|
19663
|
+
if (patterns.apiStyle) {
|
|
19664
|
+
items.push(`${renderer.bold("API Style:")} ${patterns.apiStyle}`);
|
|
19665
|
+
}
|
|
19666
|
+
if (patterns.styling) {
|
|
19667
|
+
items.push(`${renderer.bold("Styling:")} ${patterns.styling}`);
|
|
19668
|
+
}
|
|
19669
|
+
if (patterns.testing) {
|
|
19670
|
+
items.push(`${renderer.bold("Testing:")} ${patterns.testing}`);
|
|
19671
|
+
}
|
|
19672
|
+
if (patterns.linting) {
|
|
19673
|
+
items.push(`${renderer.bold("Linting:")} ${patterns.linting}`);
|
|
19674
|
+
}
|
|
19675
|
+
if (patterns.formatting) {
|
|
19676
|
+
items.push(`${renderer.bold("Formatting:")} ${patterns.formatting}`);
|
|
19677
|
+
}
|
|
19678
|
+
if (items.length > 0) {
|
|
19679
|
+
lines.push(renderer.list(items));
|
|
19680
|
+
}
|
|
19681
|
+
}
|
|
19682
|
+
return lines.join("\n");
|
|
19683
|
+
}
|
|
19684
|
+
generateStructureSection(renderer) {
|
|
19685
|
+
if (!this.analysis) return "";
|
|
19686
|
+
const { structure, importantFiles } = this.analysis;
|
|
19687
|
+
const lines = [];
|
|
19688
|
+
lines.push(renderer.h2("Project Structure"));
|
|
19689
|
+
lines.push("");
|
|
19690
|
+
if (structure) {
|
|
19691
|
+
if (structure.type) {
|
|
19692
|
+
lines.push(renderer.keyValue("Structure Type", structure.type));
|
|
19693
|
+
}
|
|
19694
|
+
if (structure.srcDir) {
|
|
19695
|
+
lines.push(renderer.keyValue("Source Directory", renderer.code(`${structure.srcDir}/`)));
|
|
19696
|
+
}
|
|
19697
|
+
if (structure.testDir) {
|
|
19698
|
+
lines.push(renderer.keyValue("Test Directory", renderer.code(`${structure.testDir}/`)));
|
|
19699
|
+
}
|
|
19700
|
+
if (structure.hasWorkspaces && structure.workspaces) {
|
|
19701
|
+
lines.push(renderer.keyValue("Workspaces", structure.workspaces.join(", ")));
|
|
19702
|
+
}
|
|
19703
|
+
lines.push("");
|
|
19704
|
+
}
|
|
19705
|
+
if (importantFiles.length > 0) {
|
|
19706
|
+
lines.push(renderer.h3("Important Files"));
|
|
19707
|
+
lines.push(renderer.list(importantFiles.slice(0, 15).map((f) => renderer.code(f))));
|
|
19708
|
+
}
|
|
19709
|
+
return lines.join("\n");
|
|
19710
|
+
}
|
|
19711
|
+
generateGuidelinesSection(_agent, renderer) {
|
|
19712
|
+
if (!this.analysis) return "";
|
|
19713
|
+
const { stack, patterns } = this.analysis;
|
|
19714
|
+
const lines = [];
|
|
19715
|
+
lines.push(renderer.h2("Development Guidelines"));
|
|
19716
|
+
lines.push("");
|
|
19717
|
+
const hasReact = stack.frameworks.some((f) => f.name === "react" || f.name === "nextjs");
|
|
19718
|
+
const hasVue = stack.frameworks.some((f) => f.name === "vue" || f.name === "nuxt");
|
|
19719
|
+
const hasTypeScript = this.analysis.languages.some((l) => l.name === "typescript");
|
|
19720
|
+
const hasTailwind = stack.styling.some((s) => s.name === "tailwindcss");
|
|
19721
|
+
const hasPrisma = stack.databases.some((d) => d.name === "prisma");
|
|
19722
|
+
const hasZod = stack.libraries.some((l) => l.name === "zod");
|
|
19723
|
+
if (hasTypeScript) {
|
|
19724
|
+
lines.push(renderer.h3("TypeScript"));
|
|
19725
|
+
lines.push(renderer.list([
|
|
19726
|
+
"Use strict TypeScript with proper type annotations",
|
|
19727
|
+
"Prefer `interface` for object types, `type` for unions/intersections",
|
|
19728
|
+
"Avoid `any` - use `unknown` when type is uncertain"
|
|
19729
|
+
]));
|
|
19730
|
+
lines.push("");
|
|
19731
|
+
}
|
|
19732
|
+
if (hasReact) {
|
|
19733
|
+
lines.push(renderer.h3("React"));
|
|
19734
|
+
const reactItems = [
|
|
19735
|
+
"Use functional components with hooks",
|
|
19736
|
+
"Prefer composition over inheritance",
|
|
19737
|
+
"Keep components small and focused"
|
|
19738
|
+
];
|
|
19739
|
+
if (patterns?.stateManagement) {
|
|
19740
|
+
reactItems.push(`Use ${patterns.stateManagement} for state management`);
|
|
19741
|
+
}
|
|
19742
|
+
lines.push(renderer.list(reactItems));
|
|
19743
|
+
lines.push("");
|
|
19744
|
+
}
|
|
19745
|
+
if (hasVue) {
|
|
19746
|
+
lines.push(renderer.h3("Vue"));
|
|
19747
|
+
lines.push(renderer.list([
|
|
19748
|
+
"Use Composition API with `<script setup>`",
|
|
19749
|
+
"Keep components small and focused"
|
|
19750
|
+
]));
|
|
19751
|
+
lines.push("");
|
|
19752
|
+
}
|
|
19753
|
+
if (hasTailwind) {
|
|
19754
|
+
lines.push(renderer.h3("Styling"));
|
|
19755
|
+
lines.push(renderer.list([
|
|
19756
|
+
"Use Tailwind CSS utility classes",
|
|
19757
|
+
"Follow mobile-first responsive design",
|
|
19758
|
+
"Extract repeated patterns to components"
|
|
19759
|
+
]));
|
|
19760
|
+
lines.push("");
|
|
19761
|
+
}
|
|
19762
|
+
if (hasPrisma) {
|
|
19763
|
+
lines.push(renderer.h3("Database"));
|
|
19764
|
+
lines.push(renderer.list([
|
|
19765
|
+
"Use Prisma for database operations",
|
|
19766
|
+
"Keep database queries in dedicated service files",
|
|
19767
|
+
"Use transactions for related operations"
|
|
19768
|
+
]));
|
|
19769
|
+
lines.push("");
|
|
19770
|
+
}
|
|
19771
|
+
if (hasZod) {
|
|
19772
|
+
lines.push(renderer.h3("Validation"));
|
|
19773
|
+
lines.push(renderer.list([
|
|
19774
|
+
"Use Zod for runtime validation",
|
|
19775
|
+
"Define schemas alongside types"
|
|
19776
|
+
]));
|
|
19777
|
+
lines.push("");
|
|
19778
|
+
}
|
|
19779
|
+
lines.push(renderer.h3("General"));
|
|
19780
|
+
lines.push(renderer.list([
|
|
19781
|
+
"Follow existing code patterns and conventions",
|
|
19782
|
+
"Write clear, self-documenting code",
|
|
19783
|
+
"Keep functions small and focused",
|
|
19784
|
+
"Add tests for new functionality"
|
|
19785
|
+
]));
|
|
19786
|
+
return lines.join("\n");
|
|
19787
|
+
}
|
|
19788
|
+
writeInstruction(instruction) {
|
|
19789
|
+
const dir = dirname13(instruction.filepath);
|
|
19790
|
+
if (!existsSync36(dir)) {
|
|
19791
|
+
mkdirSync19(dir, { recursive: true });
|
|
19792
|
+
}
|
|
19793
|
+
writeFileSync19(instruction.filepath, instruction.content, "utf-8");
|
|
19794
|
+
}
|
|
19795
|
+
formatProjectType(type) {
|
|
19796
|
+
const typeMap = {
|
|
19797
|
+
"web-app": "Web Application",
|
|
19798
|
+
"api": "API / Backend",
|
|
19799
|
+
"cli": "CLI Tool",
|
|
19800
|
+
"library": "Library / Package",
|
|
19801
|
+
"mobile": "Mobile Application",
|
|
19802
|
+
"desktop": "Desktop Application",
|
|
19803
|
+
"unknown": "Project"
|
|
19804
|
+
};
|
|
19805
|
+
return typeMap[type] || type;
|
|
19806
|
+
}
|
|
19807
|
+
capitalize(str) {
|
|
19808
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
19809
|
+
}
|
|
19810
|
+
};
|
|
19811
|
+
function generatePrimer(projectPath, options = {}) {
|
|
19812
|
+
const generator = new PrimerGenerator(projectPath, options);
|
|
19813
|
+
return generator.generate();
|
|
19814
|
+
}
|
|
19815
|
+
function generatePrimerForAgent(projectPath, agent, options = {}) {
|
|
19816
|
+
return generatePrimer(projectPath, { ...options, agents: [agent] });
|
|
19817
|
+
}
|
|
19818
|
+
function analyzeForPrimer(projectPath) {
|
|
19819
|
+
const generator = new PrimerGenerator(projectPath, { analyzeOnly: true });
|
|
19820
|
+
const result = generator.generate();
|
|
19821
|
+
return result.analysis;
|
|
19822
|
+
}
|
|
18519
19823
|
export {
|
|
18520
19824
|
AGENT_CLI_CONFIGS,
|
|
18521
19825
|
AGENT_CONFIG,
|
|
18522
19826
|
AGENT_DISCOVERY_PATHS,
|
|
18523
19827
|
AGENT_FORMAT_MAP,
|
|
19828
|
+
AGENT_INSTRUCTION_TEMPLATES,
|
|
18524
19829
|
AGENT_SKILL_FORMATS,
|
|
18525
19830
|
AIManager,
|
|
18526
19831
|
AISearch,
|
|
@@ -18584,6 +19889,8 @@ export {
|
|
|
18584
19889
|
PlanValidator,
|
|
18585
19890
|
PluginLoader,
|
|
18586
19891
|
PluginManager,
|
|
19892
|
+
PrimerAnalyzer,
|
|
19893
|
+
PrimerGenerator,
|
|
18587
19894
|
ProjectDetector,
|
|
18588
19895
|
RecommendationEngine,
|
|
18589
19896
|
RuleBasedCompressor,
|
|
@@ -18613,6 +19920,8 @@ export {
|
|
|
18613
19920
|
WorkflowOrchestrator,
|
|
18614
19921
|
addToManifest,
|
|
18615
19922
|
agentExists,
|
|
19923
|
+
analyzeForPrimer,
|
|
19924
|
+
analyzePrimer,
|
|
18616
19925
|
analyzeProject,
|
|
18617
19926
|
benchmarkSkill,
|
|
18618
19927
|
buildSkillIndex,
|
|
@@ -18685,6 +19994,8 @@ export {
|
|
|
18685
19994
|
fromCanonicalAgent,
|
|
18686
19995
|
generateComparisonNotes,
|
|
18687
19996
|
generateManifestFromInstalled,
|
|
19997
|
+
generatePrimer,
|
|
19998
|
+
generatePrimerForAgent,
|
|
18688
19999
|
generateRecommendations,
|
|
18689
20000
|
generateSkillsConfig,
|
|
18690
20001
|
getAgentCLIConfig,
|