@specverse/engines 4.1.19 → 4.1.21

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.
Files changed (22) hide show
  1. package/dist/ai/behavior-regenerate.d.ts +24 -0
  2. package/dist/ai/behavior-regenerate.d.ts.map +1 -0
  3. package/dist/ai/behavior-regenerate.js +41 -0
  4. package/dist/ai/behavior-regenerate.js.map +1 -0
  5. package/dist/ai/index.d.ts +2 -0
  6. package/dist/ai/index.d.ts.map +1 -1
  7. package/dist/ai/index.js +3 -0
  8. package/dist/ai/index.js.map +1 -1
  9. package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +1 -1
  10. package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js +1 -1
  11. package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +81 -0
  12. package/dist/libs/instance-factories/services/templates/prisma/ai-behaviors-generator.js +153 -3
  13. package/dist/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.js +7 -1
  14. package/dist/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.js.bak +244 -0
  15. package/dist/realize/index.js.bak +758 -0
  16. package/libs/instance-factories/applications/templates/react/package-json-generator.ts +1 -1
  17. package/libs/instance-factories/applications/templates/react/runtime-package-json-generator.ts +1 -1
  18. package/libs/instance-factories/cli/templates/commander/command-generator.ts +81 -0
  19. package/libs/instance-factories/services/templates/prisma/ai-behaviors-generator.ts +213 -2
  20. package/libs/instance-factories/tools/templates/mcp/static/package.json +2 -2
  21. package/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.ts +7 -1
  22. package/package.json +1 -1
@@ -0,0 +1,244 @@
1
+ import { existsSync, readdirSync, statSync, mkdirSync, writeFileSync, copyFileSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ const __generatorDir = dirname(fileURLToPath(import.meta.url));
5
+ function generateVSCodeExtension(context) {
6
+ const { spec, outputDir } = context;
7
+ const extensionDir = join(outputDir || ".", "tools", "vscode-extension");
8
+ if (!existsSync(extensionDir)) mkdirSync(extensionDir, { recursive: true });
9
+ const distribution = extractDistribution(spec);
10
+ let cliCommands = [];
11
+ if (distribution?.commands) {
12
+ cliCommands = distribution.commands.map((cmd) => {
13
+ const parts = (cmd.from || cmd.command || "").split(".");
14
+ const name = parts[parts.length - 1] || "unknown";
15
+ return {
16
+ command: `specverse.${name}`,
17
+ title: cmd.title || `${capitalize(name)}: ${cmd.description || ""}`,
18
+ category: "SpecVerse"
19
+ };
20
+ });
21
+ }
22
+ if (cliCommands.length === 0) {
23
+ cliCommands = extractCLICommands(spec);
24
+ }
25
+ if (cliCommands.length === 0) {
26
+ cliCommands = getStandardCommands();
27
+ }
28
+ const entityTypes = extractEntityTypes(spec);
29
+ const specVersion = distribution?.version || spec?.metadata?.version || spec?.version || "4.0.0";
30
+ const packageJson = generatePackageJson(cliCommands, entityTypes, specVersion);
31
+ if (distribution) {
32
+ if (distribution.displayName) packageJson.displayName = distribution.displayName;
33
+ if (distribution.publisher) packageJson.publisher = distribution.publisher;
34
+ if (distribution.description) packageJson.description = distribution.description;
35
+ if (distribution.languages && distribution.languages.length > 0) {
36
+ packageJson.contributes.languages = distribution.languages.map((lang) => ({
37
+ id: lang.id,
38
+ aliases: lang.aliases || [lang.id],
39
+ extensions: lang.extensions || [],
40
+ configuration: `./language-configuration.json`
41
+ }));
42
+ packageJson.contributes.grammars = distribution.languages.filter((lang) => lang.grammar).map((lang) => ({
43
+ language: lang.id,
44
+ scopeName: lang.grammar,
45
+ path: `./syntaxes/${lang.id}.tmLanguage.json`
46
+ }));
47
+ }
48
+ if (distribution.themes && distribution.themes.length > 0) {
49
+ packageJson.contributes.themes = distribution.themes.map((theme) => ({
50
+ label: theme.name,
51
+ uiTheme: theme.type === "dark" ? "vs-dark" : theme.type === "light" ? "vs" : "hc-black",
52
+ path: `./themes/${theme.name.toLowerCase().replace(/\s+/g, "-")}-theme.json`
53
+ }));
54
+ }
55
+ }
56
+ writeFileSync(join(extensionDir, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
57
+ let staticDir = join(__generatorDir, "static");
58
+ if (!existsSync(staticDir)) {
59
+ staticDir = join(__generatorDir.replace("/dist/libs/", "/libs/"), "static");
60
+ }
61
+ if (existsSync(staticDir)) {
62
+ copyRecursive(staticDir, extensionDir);
63
+ }
64
+ const srcDir = join(extensionDir, "src");
65
+ if (!existsSync(srcDir)) mkdirSync(srcDir, { recursive: true });
66
+ const extTs = join(staticDir, "extension.ts");
67
+ if (existsSync(extTs)) {
68
+ copyFileSync(extTs, join(srcDir, "extension.ts"));
69
+ }
70
+ const buildScript = `const esbuild = require('esbuild');
71
+ esbuild.build({
72
+ entryPoints: ['src/extension.ts'],
73
+ bundle: true,
74
+ outfile: 'dist/extension.js',
75
+ external: ['vscode'],
76
+ format: 'cjs',
77
+ platform: 'node',
78
+ }).catch(() => process.exit(1));
79
+ `;
80
+ const scriptsDir = join(extensionDir, "scripts");
81
+ if (!existsSync(scriptsDir)) mkdirSync(scriptsDir, { recursive: true });
82
+ writeFileSync(join(scriptsDir, "build.js"), buildScript);
83
+ return `VSCode extension generated in: ${extensionDir}
84
+ ${cliCommands.length} commands, ${entityTypes.length} entity keywords`;
85
+ }
86
+ function extractDistribution(spec) {
87
+ const allDistributions = [];
88
+ if (spec?.distributions) {
89
+ const entries = Array.isArray(spec.distributions) ? spec.distributions : Object.entries(spec.distributions).map(([name, data]) => ({ name, ...data }));
90
+ allDistributions.push(...entries);
91
+ }
92
+ const components = spec?.components || {};
93
+ const componentList = Array.isArray(components) ? components : Object.values(components);
94
+ for (const comp of componentList) {
95
+ const distributions = comp?.distributions;
96
+ if (!distributions) continue;
97
+ const distEntries = Array.isArray(distributions) ? distributions : Object.entries(distributions).map(([name, data]) => ({ name, ...data }));
98
+ allDistributions.push(...distEntries);
99
+ }
100
+ for (const dist of allDistributions) {
101
+ if (dist.type === "ide") return dist;
102
+ }
103
+ return allDistributions.length > 0 ? allDistributions[0] : null;
104
+ }
105
+ function extractCLICommands(spec) {
106
+ const commands = [];
107
+ const components = spec?.components || {};
108
+ const componentList = Array.isArray(components) ? components : Object.entries(components).map(([name, data]) => ({ name, ...data }));
109
+ for (const comp of componentList) {
110
+ const cliCommands = comp?.commands;
111
+ if (!cliCommands) continue;
112
+ for (const [rootName, rootDef] of Object.entries(cliCommands)) {
113
+ const subcommands = rootDef?.subcommands || {};
114
+ for (const [subName, subDef] of Object.entries(subcommands)) {
115
+ const sub = subDef;
116
+ const nestedSubs = sub?.subcommands;
117
+ if (nestedSubs) {
118
+ for (const [nestedName, nestedDef] of Object.entries(nestedSubs)) {
119
+ commands.push({
120
+ command: `specverse.${subName}.${nestedName}`,
121
+ title: `${capitalize(subName)} ${capitalize(nestedName)}: ${nestedDef.description || ""}`,
122
+ category: "SpecVerse"
123
+ });
124
+ }
125
+ } else {
126
+ commands.push({
127
+ command: `specverse.${subName}`,
128
+ title: `${capitalize(subName)}: ${sub.description || ""}`,
129
+ category: "SpecVerse"
130
+ });
131
+ }
132
+ }
133
+ }
134
+ }
135
+ return commands;
136
+ }
137
+ function extractEntityTypes(spec) {
138
+ const types = /* @__PURE__ */ new Set();
139
+ const components = spec?.components || [];
140
+ for (const component of Array.isArray(components) ? components : Object.values(components)) {
141
+ const comp = component;
142
+ const models = comp?.models;
143
+ if (models) {
144
+ if (Array.isArray(models)) {
145
+ models.forEach((m) => types.add(m.name));
146
+ } else {
147
+ Object.keys(models).forEach((name) => types.add(name));
148
+ }
149
+ }
150
+ }
151
+ return [...types];
152
+ }
153
+ function generatePackageJson(commands, _entityTypes, specVersion = "1.0.0") {
154
+ return {
155
+ name: "specverse",
156
+ displayName: "SpecVerse",
157
+ description: "SpecVerse specification language support \u2014 syntax highlighting, validation, IntelliSense",
158
+ version: specVersion,
159
+ publisher: "specverse",
160
+ engines: { vscode: "^1.80.0" },
161
+ categories: ["Programming Languages", "Linters", "Snippets"],
162
+ activationEvents: ["onLanguage:specverse"],
163
+ main: "./dist/extension.js",
164
+ contributes: {
165
+ languages: [{
166
+ id: "specverse",
167
+ aliases: ["SpecVerse", "specly"],
168
+ extensions: [".specly", ".specverse"],
169
+ configuration: "./language-configuration.json"
170
+ }],
171
+ grammars: [{
172
+ language: "specverse",
173
+ scopeName: "source.specverse",
174
+ path: "./syntaxes/specverse.tmLanguage.json"
175
+ }],
176
+ jsonValidation: [{
177
+ fileMatch: ["*.specly", "*.specverse"],
178
+ url: "./schemas/specverse-v3-schema.json"
179
+ }],
180
+ themes: [
181
+ { label: "SpecVerse Dark", uiTheme: "vs-dark", path: "./themes/specverse-complete-theme.json" },
182
+ { label: "SpecVerse Basic", uiTheme: "vs-dark", path: "./themes/specverse-basic-theme.json" }
183
+ ],
184
+ commands: commands.map((c) => ({
185
+ command: c.command,
186
+ title: c.title,
187
+ category: c.category
188
+ }))
189
+ },
190
+ scripts: {
191
+ "vscode:prepublish": "npm run build",
192
+ build: "node scripts/build.js",
193
+ package: "npx @vscode/vsce package"
194
+ },
195
+ devDependencies: {
196
+ "@types/vscode": "^1.80.0",
197
+ "@vscode/vsce": "^3.0.0",
198
+ esbuild: "^0.25.0"
199
+ },
200
+ overrides: {
201
+ // Force the patched version of lodash through @vscode/vsce →
202
+ // @secretlint → @textlint transitive chain (4.17.23 has a
203
+ // code-injection advisory in `_.template`).
204
+ lodash: "^4.18.1"
205
+ }
206
+ };
207
+ }
208
+ function copyRecursive(src, dest) {
209
+ for (const entry of readdirSync(src)) {
210
+ if (entry === "extension.ts") continue;
211
+ const srcPath = join(src, entry);
212
+ const destPath = join(dest, entry);
213
+ if (statSync(srcPath).isDirectory()) {
214
+ if (!existsSync(destPath)) mkdirSync(destPath, { recursive: true });
215
+ copyRecursive(srcPath, destPath);
216
+ } else {
217
+ copyFileSync(srcPath, destPath);
218
+ }
219
+ }
220
+ }
221
+ function getStandardCommands() {
222
+ return [
223
+ { command: "specverse.validate", title: "Validate specification", category: "SpecVerse" },
224
+ { command: "specverse.infer", title: "Infer full architecture", category: "SpecVerse" },
225
+ { command: "specverse.realize", title: "Generate code from specification", category: "SpecVerse" },
226
+ { command: "specverse.init", title: "Initialize new project", category: "SpecVerse" },
227
+ { command: "specverse.gen.diagrams", title: "Generate Mermaid diagrams", category: "SpecVerse" },
228
+ { command: "specverse.gen.docs", title: "Generate documentation", category: "SpecVerse" },
229
+ { command: "specverse.gen.uml", title: "Generate UML diagrams", category: "SpecVerse" },
230
+ { command: "specverse.dev.format", title: "Format .specly file", category: "SpecVerse" },
231
+ { command: "specverse.dev.watch", title: "Watch and validate on change", category: "SpecVerse" },
232
+ { command: "specverse.dev.quick", title: "Quick validation", category: "SpecVerse" },
233
+ { command: "specverse.cache", title: "Manage import cache", category: "SpecVerse" },
234
+ { command: "specverse.ai.docs", title: "Generate AI implementation prompt", category: "SpecVerse" },
235
+ { command: "specverse.ai.suggest", title: "Get spec improvement suggestions", category: "SpecVerse" },
236
+ { command: "specverse.ai.template", title: "Load AI prompt template", category: "SpecVerse" }
237
+ ];
238
+ }
239
+ function capitalize(str) {
240
+ return str.charAt(0).toUpperCase() + str.slice(1);
241
+ }
242
+ export {
243
+ generateVSCodeExtension as default
244
+ };