@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 +2 -1
- package/commands/init/init-project.js +24 -29
- package/commands/profile/index.js +36 -3
- package/commands/profile/profile.bundle.js +23342 -0
- package/package.json +13 -2
- package/templates/0.8.2/{srcdoc.schema.json → profile.schema.json} +1 -1
- package/templates/0.8.2/seed.md +4 -4
- package/commands/profile/find-handlers.js +0 -351
- package/commands/profile/find-transmissions.js +0 -54
- package/commands/profile/profile.js +0 -272
- package/commands/profile/rollup.config.js +0 -22
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.
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
102
|
+
function fallbackProfileSchema() {
|
|
108
103
|
return `{
|
|
109
104
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
110
|
-
"title": "
|
|
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
|
|
123
|
-
The
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 ${
|
|
211
|
-
await copyOrWriteFallback(
|
|
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
|
-
|
|
233
|
+
profile: {
|
|
239
234
|
path: rel(llmPosix, docFile),
|
|
240
|
-
schema: '
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
+
}
|