@vizualmodel/vmblu-cli 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # CLI for vmblu
2
- This folder contains the CLI commands that are available for vmblu. Currently there is only the 'init' and 'help' command, but others will follow.
2
+ This folder contains the CLI commands that are available for vmblu.
3
3
 
4
4
 
5
5
  ## Folder layout
@@ -9,6 +9,7 @@ vmblu/
9
9
  cli/ # your CLI source
10
10
  commands/
11
11
  init/
12
+ profile/
12
13
  migrate/
13
14
  templates/
14
15
  0.8.2/
@@ -1,10 +1,10 @@
1
1
  // core/initProject.js
2
2
  // Node 18+ (fs/promises, crypto). No external deps.
3
- import * as fs from 'fs/promises';
4
- import * as fssync from 'fs';
5
- import path from 'path';
6
- //import crypto from 'crypto';
7
- import { makePackageJson } from './make-package-json.js';
3
+ import * as fs from 'fs/promises';
4
+ import * as fssync from 'fs';
5
+ import path from 'path';
6
+ //import crypto from 'crypto';
7
+ import { makePackageJson } from './make-package-json.js';
8
8
 
9
9
  function rel(from, to) {
10
10
  return path.posix.join(...path.relative(from, to).split(path.sep));
@@ -73,14 +73,9 @@ function defaultModel(projectName) {
73
73
  function defaultDoc(projectName) {
74
74
  const now = new Date().toISOString();
75
75
  return JSON.stringify({
76
- project: projectName,
77
- generator: "vmblu-docgen",
78
- generatorVersion: "0.0.0",
79
- created: now,
80
- files: [],
81
- nodes: [],
82
- pins: [],
83
- handlers: []
76
+ version: "0.0.0",
77
+ generatedAt: now,
78
+ entries: {}
84
79
  }, null, 2);
85
80
  }
86
81
 
@@ -104,10 +99,10 @@ function fallbackSchema() {
104
99
  }`;
105
100
  }
106
101
 
107
- function fallbackSrcdocSchema() {
102
+ function fallbackProfileSchema() {
108
103
  return `{
109
104
  "$schema": "https://json-schema.org/draft/2020-12/schema",
110
- "title": "srcdoc.schema (placeholder)",
105
+ "title": "profile.schema (placeholder)",
111
106
  "type": "object",
112
107
  "description": "Placeholder schema. Replace with official version."
113
108
  }`;
@@ -119,16 +114,16 @@ function fallbackSeed() {
119
114
  vmblu (Vizual Model Blueprint) is a graphical editor that maintains a visual, runnable model of a software system.
120
115
  vmblu models software as interconnected nodes that pass messages via pins.
121
116
  The model has a well defined format described by a schema. An additional annex gives semantic background information about the schema.
122
- The parameter profiles of messages and where in the actual source code messages are received and sent, is stored in a second file, the srcdoc file.
123
- The srcdoc file is generated automatically by vmblu and is only to be consulted, not written.
117
+ The parameter profiles of messages and where in the actual source code messages are received and sent, is stored in a second file, the profile file.
118
+ The profile file is generated automatically by vmblu and is only to be consulted, not written.
124
119
 
125
120
  You are an expert **architecture + code copilot** for **vmblu** .
126
- You can find the location of the model file, the model schema, the model annex, the srcdoc file and the srcdoc schema in the 'manifest.json' file of this project.
121
+ You can find the location of the model file, the model schema, the model annex, the profile file and the profile schema in the 'manifest.json' file of this project.
127
122
  The location of all other files in the project can be found via the model file.
128
123
 
129
124
  Your job is to co-design the architecture and the software for the system.
130
125
  For modifications of the model, always follow the schema.
131
- If the srcdoc does not contain profile information it could be that the code for a message has not been written yet, this should not stop you from continuing
126
+ If the profile does not contain profile information it could be that the code for a message has not been written yet, this should not stop you from continuing
132
127
  `}
133
128
 
134
129
  /**
@@ -178,7 +173,7 @@ async function initProject(opts) {
178
173
  // Template sources
179
174
  const schemaSrc = path.join(templatesDir, schemaVersion, 'vmblu.schema.json');
180
175
  const annexSrc = path.join(templatesDir, schemaVersion, 'vmblu.annex.md');
181
- const srcdocSchemaSrc = path.join(templatesDir, schemaVersion, 'srcdoc.schema.json');
176
+ const profileSchemaSrc = path.join(templatesDir, schemaVersion, 'profile.schema.json');
182
177
  const seedSrc = path.join(templatesDir, schemaVersion, 'seed.md');
183
178
 
184
179
  // 1) Create folders
@@ -197,7 +192,7 @@ async function initProject(opts) {
197
192
  // 3) Copy schema + annex into llm/
198
193
  const schemaDst = path.join(llmDir, 'vmblu.schema.json');
199
194
  const annexDst = path.join(llmDir, 'vmblu.annex.md');
200
- const srcdocSchemaDst = path.join(llmDir, 'srcdoc.schema.json');
195
+ const profileSchemaDst = path.join(llmDir, 'profile.schema.json');
201
196
  const seedDst = path.join(llmDir, 'seed.md');
202
197
 
203
198
 
@@ -207,8 +202,8 @@ async function initProject(opts) {
207
202
  ui.info(`copy ${annexSrc} -> ${annexDst}${force ? ' (force)' : ''}`);
208
203
  await copyOrWriteFallback(annexSrc, annexDst, fallbackAnnex(), { force, dry: dryRun });
209
204
 
210
- ui.info(`copy ${srcdocSchemaSrc} -> ${srcdocSchemaDst}${force ? ' (force)' : ''}`);
211
- await copyOrWriteFallback(srcdocSchemaSrc, srcdocSchemaDst, fallbackSrcdocSchema(), { force, dry: dryRun });
205
+ ui.info(`copy ${profileSchemaSrc} -> ${profileSchemaDst}${force ? ' (force)' : ''}`);
206
+ await copyOrWriteFallback(profileSchemaSrc, profileSchemaDst, fallbackProfileSchema(), { force, dry: dryRun });
212
207
 
213
208
  ui.info(`copy ${seedSrc} -> ${seedDst}${force ? ' (force)' : ''}`);
214
209
  await copyOrWriteFallback(seedSrc, seedDst, fallbackSeed(), { force, dry: dryRun });
@@ -235,9 +230,9 @@ async function initProject(opts) {
235
230
  schema: 'vmblu.schema.json',
236
231
  annex: 'vmblu.annex.md',
237
232
  },
238
- srcdoc: {
233
+ profile: {
239
234
  path: rel(llmPosix, docFile),
240
- schema: 'srcdoc.schema.json',
235
+ schema: 'profile.schema.json',
241
236
  },
242
237
  };
243
238
 
@@ -251,7 +246,7 @@ async function initProject(opts) {
251
246
  }
252
247
 
253
248
  // 5) Make the package file
254
- makePackageJson({ absTarget, projectName, force, dryRun, addCliDep: true, cliVersion: "^0.1.0" }, ui);
249
+ makePackageJson({ absTarget, projectName, force, dryRun, addCliDep: true, cliVersion: "^0.1.0" }, ui);
255
250
 
256
251
  // 6) Final tree hint
257
252
  ui.info(`\nScaffold complete${dryRun ? ' (dry run)' : ''}:\n` +
@@ -264,7 +259,7 @@ async function initProject(opts) {
264
259
  manifest.json
265
260
  vmblu.schema.json
266
261
  vmblu.annex.md
267
- srcdoc.schema.json
262
+ profile.schema.json
268
263
  session/
269
264
  nodes/\n`);
270
265
 
@@ -277,7 +272,7 @@ async function initProject(opts) {
277
272
  doc: docFile,
278
273
  schema: schemaDst,
279
274
  annex: annexDst,
280
- srdocSchema: srcdocSchemaDst,
275
+ profileSchema: profileSchemaDst,
281
276
  manifest: path.join(llmDir, 'manifest.json')
282
277
  },
283
278
  dryRun,
@@ -285,4 +280,4 @@ async function initProject(opts) {
285
280
  };
286
281
  }
287
282
 
288
- export { initProject };
283
+ export { initProject };
@@ -1,4 +1,7 @@
1
- import { profile } from './profile.js';
1
+ const bundleUrl = new URL('./profile.bundle.js', import.meta.url);
2
+ const sourceUrl = new URL('./profile.js', import.meta.url);
3
+
4
+ let profileModulePromise;
2
5
 
3
6
  export const command = 'profile <model-file>';
4
7
  export const describe = 'Find message handlers and message transmissions.';
@@ -9,8 +12,38 @@ export const builder = [
9
12
  { flag: '--changed <files...>', desc: 'only check changed files' },
10
13
  { flag: '--deleted <files...>', desc: 'remove data from deleted files' },
11
14
  { flag: '--delta-file <path>', desc: 'write the delta to a file' },
12
- { flag: '--reason <text>', desc: 'information' },
15
+ { flag: '--reason <text>', desc: 'information' }
13
16
  ];
14
17
 
15
- export const handler = profile;
18
+ export async function profile(argv) {
19
+ const mod = await getProfileModule();
20
+ if (typeof mod.profile !== 'function') {
21
+ throw new Error('Profile module does not export a runnable profile function.');
22
+ }
23
+ return mod.profile(argv);
24
+ }
25
+
26
+ export const handler = async (argv) => profile(argv);
27
+
28
+ function getProfileModule() {
29
+ if (!profileModulePromise) {
30
+ profileModulePromise = loadProfileModule();
31
+ }
32
+ return profileModulePromise;
33
+ }
34
+
35
+ async function loadProfileModule() {
36
+ try {
37
+ return await import(bundleUrl);
38
+ } catch (err) {
39
+ if (isModuleNotFound(err)) {
40
+ return import(sourceUrl);
41
+ }
42
+ throw err;
43
+ }
44
+ }
16
45
 
46
+ function isModuleNotFound(err) {
47
+ const message = err?.message ?? '';
48
+ return err?.code === 'ERR_MODULE_NOT_FOUND' || message.includes('Cannot find module');
49
+ }