@famgia/omnify-laravel 0.0.88 → 0.0.90
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/dist/{chunk-YVVAJA3T.js → chunk-2QSKZS63.js} +188 -12
- package/dist/chunk-2QSKZS63.js.map +1 -0
- package/dist/index.cjs +190 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -1
- package/dist/index.d.ts +48 -1
- package/dist/index.js +5 -1
- package/dist/plugin.cjs +186 -11
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +5 -5
- package/scripts/postinstall.js +29 -36
- package/stubs/ai-guides/README.md.stub +95 -0
- package/stubs/ai-guides/claude-agents/architect.md.stub +150 -0
- package/stubs/ai-guides/claude-agents/developer.md.stub +190 -0
- package/stubs/ai-guides/claude-agents/reviewer.md.stub +134 -0
- package/stubs/ai-guides/claude-agents/tester.md.stub +196 -0
- package/stubs/ai-guides/claude-checklists/backend.md.stub +112 -0
- package/stubs/ai-guides/claude-omnify/antdesign-guide.md.stub +401 -0
- package/stubs/ai-guides/claude-omnify/config-guide.md.stub +253 -0
- package/stubs/ai-guides/claude-omnify/japan-guide.md.stub +186 -0
- package/stubs/ai-guides/claude-omnify/laravel-guide.md.stub +61 -0
- package/stubs/ai-guides/claude-omnify/react-form-guide.md.stub +259 -0
- package/stubs/ai-guides/claude-omnify/schema-guide.md.stub +115 -0
- package/stubs/ai-guides/claude-omnify/typescript-guide.md.stub +310 -0
- package/stubs/ai-guides/claude-rules/naming.md.stub +364 -0
- package/stubs/ai-guides/claude-rules/performance.md.stub +251 -0
- package/stubs/ai-guides/claude-rules/security.md.stub +159 -0
- package/stubs/ai-guides/claude-workflows/bug-fix.md.stub +201 -0
- package/stubs/ai-guides/claude-workflows/code-review.md.stub +164 -0
- package/stubs/ai-guides/claude-workflows/new-feature.md.stub +327 -0
- package/stubs/ai-guides/cursor/laravel-controller.mdc.stub +391 -0
- package/stubs/ai-guides/cursor/laravel-request.mdc.stub +112 -0
- package/stubs/ai-guides/cursor/laravel-resource.mdc.stub +73 -0
- package/stubs/ai-guides/cursor/laravel-review.mdc.stub +69 -0
- package/stubs/ai-guides/cursor/laravel-testing.mdc.stub +138 -0
- package/stubs/ai-guides/cursor/laravel.mdc.stub +82 -0
- package/stubs/ai-guides/cursor/omnify.mdc.stub +58 -0
- package/stubs/ai-guides/laravel/README.md.stub +59 -0
- package/stubs/ai-guides/laravel/architecture.md.stub +424 -0
- package/stubs/ai-guides/laravel/controller.md.stub +484 -0
- package/stubs/ai-guides/laravel/datetime.md.stub +334 -0
- package/stubs/ai-guides/laravel/openapi.md.stub +369 -0
- package/stubs/ai-guides/laravel/request.md.stub +450 -0
- package/stubs/ai-guides/laravel/resource.md.stub +516 -0
- package/stubs/ai-guides/laravel/service.md.stub +503 -0
- package/stubs/ai-guides/laravel/testing.md.stub +1504 -0
- package/ai-guides/laravel-guide.md +0 -461
- package/dist/chunk-YVVAJA3T.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/plugin.ts
|
|
2
|
-
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
3
|
-
import { join } from "path";
|
|
2
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2, readdirSync as readdirSync2 } from "fs";
|
|
3
|
+
import { join as join2 } from "path";
|
|
4
4
|
|
|
5
5
|
// src/migration/schema-builder.ts
|
|
6
6
|
import { resolveLocalizedString } from "@famgia/omnify-types";
|
|
@@ -3921,6 +3921,161 @@ function getResourcePath(resource) {
|
|
|
3921
3921
|
return resource.path;
|
|
3922
3922
|
}
|
|
3923
3923
|
|
|
3924
|
+
// src/ai-guides/generator.ts
|
|
3925
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
3926
|
+
import { resolve, dirname, join } from "path";
|
|
3927
|
+
import { fileURLToPath } from "url";
|
|
3928
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
3929
|
+
var __dirname = dirname(__filename);
|
|
3930
|
+
function getStubsDir() {
|
|
3931
|
+
const devPath = resolve(__dirname, "../../stubs/ai-guides");
|
|
3932
|
+
if (existsSync(devPath)) {
|
|
3933
|
+
return devPath;
|
|
3934
|
+
}
|
|
3935
|
+
const distPath = resolve(__dirname, "../stubs/ai-guides");
|
|
3936
|
+
if (existsSync(distPath)) {
|
|
3937
|
+
return distPath;
|
|
3938
|
+
}
|
|
3939
|
+
throw new Error("AI guides stubs not found");
|
|
3940
|
+
}
|
|
3941
|
+
function extractLaravelBasePath(modelsPath) {
|
|
3942
|
+
if (!modelsPath) return "app";
|
|
3943
|
+
const normalized = modelsPath.replace(/\\/g, "/");
|
|
3944
|
+
const match = normalized.match(/^(.+?)\/Models(?:\/.*)?$/);
|
|
3945
|
+
if (match && match[1]) {
|
|
3946
|
+
return match[1];
|
|
3947
|
+
}
|
|
3948
|
+
const parts = normalized.split("/").filter(Boolean);
|
|
3949
|
+
if (parts.length > 1) {
|
|
3950
|
+
return parts.slice(0, -1).join("/");
|
|
3951
|
+
}
|
|
3952
|
+
return "app";
|
|
3953
|
+
}
|
|
3954
|
+
function replacePlaceholders(content, basePath) {
|
|
3955
|
+
return content.replace(/\{\{LARAVEL_BASE\}\}/g, basePath);
|
|
3956
|
+
}
|
|
3957
|
+
function copyStubs(srcDir, destDir, transform) {
|
|
3958
|
+
const writtenFiles = [];
|
|
3959
|
+
if (!existsSync(srcDir)) {
|
|
3960
|
+
return writtenFiles;
|
|
3961
|
+
}
|
|
3962
|
+
if (!existsSync(destDir)) {
|
|
3963
|
+
mkdirSync(destDir, { recursive: true });
|
|
3964
|
+
}
|
|
3965
|
+
const entries = readdirSync(srcDir, { withFileTypes: true });
|
|
3966
|
+
for (const entry of entries) {
|
|
3967
|
+
const srcPath = join(srcDir, entry.name);
|
|
3968
|
+
if (entry.isDirectory()) {
|
|
3969
|
+
const subDestDir = join(destDir, entry.name);
|
|
3970
|
+
const subFiles = copyStubs(srcPath, subDestDir, transform);
|
|
3971
|
+
writtenFiles.push(...subFiles);
|
|
3972
|
+
} else if (entry.isFile() && entry.name.endsWith(".stub")) {
|
|
3973
|
+
const destName = entry.name.slice(0, -5);
|
|
3974
|
+
const destPath = join(destDir, destName);
|
|
3975
|
+
let content = readFileSync(srcPath, "utf-8");
|
|
3976
|
+
if (transform) {
|
|
3977
|
+
content = transform(content);
|
|
3978
|
+
}
|
|
3979
|
+
writeFileSync(destPath, content);
|
|
3980
|
+
writtenFiles.push(destPath);
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
return writtenFiles;
|
|
3984
|
+
}
|
|
3985
|
+
function generateAIGuides(rootDir, options = {}) {
|
|
3986
|
+
const stubsDir = getStubsDir();
|
|
3987
|
+
const basePath = options.laravelBasePath || extractLaravelBasePath(options.modelsPath);
|
|
3988
|
+
const result = {
|
|
3989
|
+
claudeGuides: 0,
|
|
3990
|
+
claudeRules: 0,
|
|
3991
|
+
claudeChecklists: 0,
|
|
3992
|
+
claudeWorkflows: 0,
|
|
3993
|
+
claudeAgents: 0,
|
|
3994
|
+
claudeOmnify: 0,
|
|
3995
|
+
cursorRules: 0,
|
|
3996
|
+
files: []
|
|
3997
|
+
};
|
|
3998
|
+
const readmeSrcPath = join(stubsDir, "README.md.stub");
|
|
3999
|
+
if (existsSync(readmeSrcPath)) {
|
|
4000
|
+
const readmeDestDir = resolve(rootDir, ".claude/omnify");
|
|
4001
|
+
if (!existsSync(readmeDestDir)) {
|
|
4002
|
+
mkdirSync(readmeDestDir, { recursive: true });
|
|
4003
|
+
}
|
|
4004
|
+
const content = readFileSync(readmeSrcPath, "utf-8");
|
|
4005
|
+
writeFileSync(resolve(readmeDestDir, "README.md"), content);
|
|
4006
|
+
result.files.push(resolve(readmeDestDir, "README.md"));
|
|
4007
|
+
}
|
|
4008
|
+
const claudeSrcDir = join(stubsDir, "laravel");
|
|
4009
|
+
const claudeDestDir = resolve(rootDir, ".claude/omnify/guides/laravel");
|
|
4010
|
+
if (existsSync(claudeSrcDir)) {
|
|
4011
|
+
const files = copyStubs(claudeSrcDir, claudeDestDir);
|
|
4012
|
+
result.claudeGuides = files.length;
|
|
4013
|
+
result.files.push(...files);
|
|
4014
|
+
}
|
|
4015
|
+
const claudeRulesSrcDir = join(stubsDir, "claude-rules");
|
|
4016
|
+
const claudeRulesDestDir = resolve(rootDir, ".claude/omnify/rules");
|
|
4017
|
+
if (existsSync(claudeRulesSrcDir)) {
|
|
4018
|
+
const files = copyStubs(claudeRulesSrcDir, claudeRulesDestDir);
|
|
4019
|
+
result.claudeRules = files.length;
|
|
4020
|
+
result.files.push(...files);
|
|
4021
|
+
}
|
|
4022
|
+
const claudeChecklistsSrcDir = join(stubsDir, "claude-checklists");
|
|
4023
|
+
const claudeChecklistsDestDir = resolve(rootDir, ".claude/omnify/checklists");
|
|
4024
|
+
if (existsSync(claudeChecklistsSrcDir)) {
|
|
4025
|
+
const files = copyStubs(claudeChecklistsSrcDir, claudeChecklistsDestDir);
|
|
4026
|
+
result.claudeChecklists = files.length;
|
|
4027
|
+
result.files.push(...files);
|
|
4028
|
+
}
|
|
4029
|
+
const claudeWorkflowsSrcDir = join(stubsDir, "claude-workflows");
|
|
4030
|
+
const claudeWorkflowsDestDir = resolve(rootDir, ".claude/omnify/workflows");
|
|
4031
|
+
if (existsSync(claudeWorkflowsSrcDir)) {
|
|
4032
|
+
const files = copyStubs(claudeWorkflowsSrcDir, claudeWorkflowsDestDir);
|
|
4033
|
+
result.claudeWorkflows = files.length;
|
|
4034
|
+
result.files.push(...files);
|
|
4035
|
+
}
|
|
4036
|
+
const claudeAgentsSrcDir = join(stubsDir, "claude-agents");
|
|
4037
|
+
const claudeAgentsDestDir = resolve(rootDir, ".claude/omnify/agents");
|
|
4038
|
+
if (existsSync(claudeAgentsSrcDir)) {
|
|
4039
|
+
const files = copyStubs(claudeAgentsSrcDir, claudeAgentsDestDir);
|
|
4040
|
+
result.claudeAgents = files.length;
|
|
4041
|
+
result.files.push(...files);
|
|
4042
|
+
}
|
|
4043
|
+
const claudeOmnifySrcDir = join(stubsDir, "claude-omnify");
|
|
4044
|
+
const claudeOmnifyDestDir = resolve(rootDir, ".claude/omnify/guides/omnify");
|
|
4045
|
+
if (existsSync(claudeOmnifySrcDir)) {
|
|
4046
|
+
const files = copyStubs(claudeOmnifySrcDir, claudeOmnifyDestDir);
|
|
4047
|
+
result.claudeOmnify = files.length;
|
|
4048
|
+
result.files.push(...files);
|
|
4049
|
+
}
|
|
4050
|
+
const cursorSrcDir = join(stubsDir, "cursor");
|
|
4051
|
+
const cursorDestDir = resolve(rootDir, ".cursor/rules/omnify");
|
|
4052
|
+
if (existsSync(cursorSrcDir)) {
|
|
4053
|
+
const files = copyStubs(
|
|
4054
|
+
cursorSrcDir,
|
|
4055
|
+
cursorDestDir,
|
|
4056
|
+
(content) => replacePlaceholders(content, basePath)
|
|
4057
|
+
);
|
|
4058
|
+
result.cursorRules = files.length;
|
|
4059
|
+
result.files.push(...files);
|
|
4060
|
+
}
|
|
4061
|
+
return result;
|
|
4062
|
+
}
|
|
4063
|
+
function shouldGenerateAIGuides(rootDir) {
|
|
4064
|
+
const claudeDir = resolve(rootDir, ".claude/omnify/guides/laravel");
|
|
4065
|
+
const cursorDir = resolve(rootDir, ".cursor/rules/omnify");
|
|
4066
|
+
if (!existsSync(claudeDir) || !existsSync(cursorDir)) {
|
|
4067
|
+
return true;
|
|
4068
|
+
}
|
|
4069
|
+
try {
|
|
4070
|
+
const claudeFiles = readdirSync(claudeDir);
|
|
4071
|
+
const cursorFiles = readdirSync(cursorDir);
|
|
4072
|
+
const hasLaravelRules = cursorFiles.some((f) => f.startsWith("laravel"));
|
|
4073
|
+
return claudeFiles.length === 0 || !hasLaravelRules;
|
|
4074
|
+
} catch {
|
|
4075
|
+
return true;
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
|
|
3924
4079
|
// src/plugin.ts
|
|
3925
4080
|
function inferLaravelRoot(providersPath) {
|
|
3926
4081
|
const normalized = providersPath.replace(/\\/g, "/");
|
|
@@ -3936,11 +4091,11 @@ function inferLaravelRoot(providersPath) {
|
|
|
3936
4091
|
}
|
|
3937
4092
|
function getExistingMigrationTables(migrationsDir) {
|
|
3938
4093
|
const existingTables = /* @__PURE__ */ new Set();
|
|
3939
|
-
if (!
|
|
4094
|
+
if (!existsSync2(migrationsDir)) {
|
|
3940
4095
|
return existingTables;
|
|
3941
4096
|
}
|
|
3942
4097
|
try {
|
|
3943
|
-
const files =
|
|
4098
|
+
const files = readdirSync2(migrationsDir);
|
|
3944
4099
|
const createMigrationPattern = /^\d{4}_\d{2}_\d{2}_\d{6}_create_(.+)_table\.php$/;
|
|
3945
4100
|
for (const file of files) {
|
|
3946
4101
|
const match = file.match(createMigrationPattern);
|
|
@@ -4106,7 +4261,7 @@ function laravelPlugin(options) {
|
|
|
4106
4261
|
customTypes: ctx.customTypes
|
|
4107
4262
|
};
|
|
4108
4263
|
const outputs = [];
|
|
4109
|
-
const migrationsDir =
|
|
4264
|
+
const migrationsDir = join2(ctx.cwd, resolved.migrationsPath);
|
|
4110
4265
|
const existingTables = getExistingMigrationTables(migrationsDir);
|
|
4111
4266
|
if (ctx.changes !== void 0) {
|
|
4112
4267
|
if (ctx.changes.length === 0) {
|
|
@@ -4206,20 +4361,20 @@ function laravelPlugin(options) {
|
|
|
4206
4361
|
const laravelRoot = inferLaravelRoot(resolved.providersPath);
|
|
4207
4362
|
const bootstrapProvidersRelPath = laravelRoot ? `${laravelRoot}/bootstrap/providers.php` : "bootstrap/providers.php";
|
|
4208
4363
|
const configAppRelPath = laravelRoot ? `${laravelRoot}/config/app.php` : "config/app.php";
|
|
4209
|
-
const bootstrapProvidersPath =
|
|
4210
|
-
const configAppPath =
|
|
4364
|
+
const bootstrapProvidersPath = join2(ctx.cwd, bootstrapProvidersRelPath);
|
|
4365
|
+
const configAppPath = join2(ctx.cwd, configAppRelPath);
|
|
4211
4366
|
let existingContent = null;
|
|
4212
4367
|
let laravelVersion;
|
|
4213
|
-
if (
|
|
4368
|
+
if (existsSync2(bootstrapProvidersPath)) {
|
|
4214
4369
|
laravelVersion = "laravel11+";
|
|
4215
4370
|
try {
|
|
4216
|
-
existingContent =
|
|
4371
|
+
existingContent = readFileSync2(bootstrapProvidersPath, "utf-8");
|
|
4217
4372
|
} catch {
|
|
4218
4373
|
existingContent = null;
|
|
4219
4374
|
}
|
|
4220
|
-
} else if (
|
|
4375
|
+
} else if (existsSync2(configAppPath)) {
|
|
4221
4376
|
try {
|
|
4222
|
-
const configContent =
|
|
4377
|
+
const configContent = readFileSync2(configAppPath, "utf-8");
|
|
4223
4378
|
if (/'providers'\s*=>\s*\[/.test(configContent)) {
|
|
4224
4379
|
laravelVersion = "laravel10-";
|
|
4225
4380
|
existingContent = configContent;
|
|
@@ -4332,6 +4487,24 @@ function laravelPlugin(options) {
|
|
|
4332
4487
|
}));
|
|
4333
4488
|
}
|
|
4334
4489
|
};
|
|
4490
|
+
const aiGuidesGenerator = {
|
|
4491
|
+
name: "laravel-ai-guides",
|
|
4492
|
+
description: "Generate AI assistant guides (Claude, Cursor) for Laravel development",
|
|
4493
|
+
generate: async (ctx) => {
|
|
4494
|
+
if (!shouldGenerateAIGuides(ctx.cwd)) {
|
|
4495
|
+
ctx.logger.debug("AI guides already exist, skipping");
|
|
4496
|
+
return [];
|
|
4497
|
+
}
|
|
4498
|
+
const result = generateAIGuides(ctx.cwd, {
|
|
4499
|
+
modelsPath: resolved.modelsPath,
|
|
4500
|
+
migrationsPath: resolved.migrationsPath,
|
|
4501
|
+
laravelBasePath: "app"
|
|
4502
|
+
});
|
|
4503
|
+
const claudeTotal = result.claudeGuides + result.claudeRules + result.claudeChecklists + result.claudeWorkflows + result.claudeAgents + result.claudeOmnify;
|
|
4504
|
+
ctx.logger.info(`Generated ${claudeTotal} Claude files, ${result.cursorRules} Cursor rules`);
|
|
4505
|
+
return [];
|
|
4506
|
+
}
|
|
4507
|
+
};
|
|
4335
4508
|
const generators = [migrationGenerator];
|
|
4336
4509
|
if (resolved.generateModels) {
|
|
4337
4510
|
generators.push(modelGenerator);
|
|
@@ -4345,6 +4518,7 @@ function laravelPlugin(options) {
|
|
|
4345
4518
|
if (resolved.generateResources) {
|
|
4346
4519
|
generators.push(resourceGenerator);
|
|
4347
4520
|
}
|
|
4521
|
+
generators.push(aiGuidesGenerator);
|
|
4348
4522
|
return {
|
|
4349
4523
|
name: "@famgia/omnify-laravel",
|
|
4350
4524
|
version: "0.0.14",
|
|
@@ -4378,6 +4552,8 @@ export {
|
|
|
4378
4552
|
generateProviderRegistration,
|
|
4379
4553
|
generateFactories,
|
|
4380
4554
|
getFactoryPath,
|
|
4555
|
+
generateAIGuides,
|
|
4556
|
+
shouldGenerateAIGuides,
|
|
4381
4557
|
laravelPlugin
|
|
4382
4558
|
};
|
|
4383
|
-
//# sourceMappingURL=chunk-
|
|
4559
|
+
//# sourceMappingURL=chunk-2QSKZS63.js.map
|