multimodel-dev-os 1.1.0 → 2.0.0
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/.ai/adapters/custom-adapter.example.yaml +9 -0
- package/.ai/adapters/registry.yaml +56 -0
- package/.ai/models/README.md +14 -0
- package/.ai/models/local-models.yaml +20 -0
- package/.ai/models/providers.yaml +29 -0
- package/.ai/models/registry.yaml +73 -0
- package/.ai/models/routing-presets.yaml +23 -0
- package/.ai/skills/custom-skill.example.md +15 -0
- package/.ai/templates/custom-template.example.yaml +19 -0
- package/.ai/templates/registry.yaml +522 -0
- package/README.md +30 -18
- package/bin/multimodel-dev-os.js +810 -91
- package/docs/.vitepress/config.js +36 -1
- package/docs/adapter-authoring.md +46 -0
- package/docs/agent-compatibility.md +51 -0
- package/docs/cli-roadmap.md +15 -18
- package/docs/final-launch.md +5 -4
- package/docs/local-models.md +48 -0
- package/docs/mobile-android.md +75 -0
- package/docs/model-compatibility.md +65 -0
- package/docs/model-routing.md +45 -0
- package/docs/npm-publishing.md +27 -0
- package/docs/package-safety.md +29 -0
- package/docs/provider-strategy.md +44 -0
- package/docs/public/llms-full.txt +82 -73
- package/docs/public/llms.txt +36 -34
- package/docs/quickstart.md +7 -6
- package/docs/registry-contribution.md +20 -0
- package/docs/release-policy.md +26 -0
- package/docs/skill-authoring.md +56 -0
- package/docs/template-authoring.md +65 -0
- package/docs/token-optimization.md +27 -0
- package/docs/v2-migration.md +31 -0
- package/docs/v2-release-checklist.md +30 -0
- package/docs/v2-roadmap.md +95 -0
- package/examples/expo-react-native-android/.ai/config.yaml +22 -0
- package/examples/expo-react-native-android/.ai/context/architecture.md +18 -0
- package/examples/expo-react-native-android/.ai/context/context-budget.md +4 -0
- package/examples/expo-react-native-android/.ai/context/model-map.md +6 -0
- package/examples/expo-react-native-android/.ai/context/project-brief.md +9 -0
- package/examples/expo-react-native-android/.ai/session-logs/.gitkeep +1 -0
- package/examples/expo-react-native-android/.ai/skills/expo-android-build.md +11 -0
- package/examples/expo-react-native-android/AGENTS.md +20 -0
- package/examples/expo-react-native-android/MEMORY.md +13 -0
- package/examples/expo-react-native-android/README.md +101 -0
- package/examples/expo-react-native-android/RUNBOOK.md +36 -0
- package/examples/expo-react-native-android/TASKS.md +14 -0
- package/examples/expo-react-native-android/app.config.ts +40 -0
- package/examples/expo-react-native-android/app.json +34 -0
- package/examples/expo-react-native-android/eas.json +26 -0
- package/examples/expo-react-native-android/jest.config.js +11 -0
- package/examples/expo-react-native-android/src/app/_layout.tsx +89 -0
- package/examples/expo-react-native-android/src/lib/secure-storage.ts +63 -0
- package/examples/expo-react-native-android/src/services/api-client.ts +106 -0
- package/package.json +3 -2
- package/scripts/install.ps1 +230 -230
- package/scripts/install.sh +1 -1
- package/scripts/prepublish-guard.js +43 -0
- package/scripts/verify.js +178 -1
package/scripts/verify.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Runs on Windows, macOS, and Linux with zero external dependencies.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { existsSync, readFileSync, statSync } from 'fs';
|
|
9
|
+
import { existsSync, readFileSync, statSync, readdirSync } from 'fs';
|
|
10
10
|
import { join, resolve, dirname } from 'path';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
import { execSync } from 'child_process';
|
|
@@ -67,6 +67,7 @@ checkFile('RUNBOOK.md');
|
|
|
67
67
|
checkFile('README.md');
|
|
68
68
|
checkFile('LICENSE');
|
|
69
69
|
checkFile('CONTRIBUTING.md');
|
|
70
|
+
checkFile('CONTRIBUTORS.md');
|
|
70
71
|
checkFile('CODE_OF_CONDUCT.md');
|
|
71
72
|
checkFile('SECURITY.md');
|
|
72
73
|
checkFile('CHANGELOG.md');
|
|
@@ -166,6 +167,15 @@ checkFile('examples/ecommerce-store/AGENTS.md');
|
|
|
166
167
|
checkFile('examples/ecommerce-store/MEMORY.md');
|
|
167
168
|
checkFile('examples/seo-landing-page/AGENTS.md');
|
|
168
169
|
checkFile('examples/seo-landing-page/MEMORY.md');
|
|
170
|
+
checkFile('examples/expo-react-native-android/AGENTS.md');
|
|
171
|
+
checkFile('examples/expo-react-native-android/MEMORY.md');
|
|
172
|
+
checkFile('examples/expo-react-native-android/app.json');
|
|
173
|
+
checkFile('examples/expo-react-native-android/eas.json');
|
|
174
|
+
checkFile('examples/expo-react-native-android/app.config.ts');
|
|
175
|
+
checkFile('examples/expo-react-native-android/jest.config.js');
|
|
176
|
+
checkFile('examples/expo-react-native-android/src/app/_layout.tsx');
|
|
177
|
+
checkFile('examples/expo-react-native-android/src/lib/secure-storage.ts');
|
|
178
|
+
checkFile('examples/expo-react-native-android/src/services/api-client.ts');
|
|
169
179
|
checkFile('examples/general-app/AGENTS.md');
|
|
170
180
|
checkFile('examples/general-app/MEMORY.md');
|
|
171
181
|
|
|
@@ -175,6 +185,7 @@ checkFile('scripts/install.sh');
|
|
|
175
185
|
checkFile('scripts/install.ps1');
|
|
176
186
|
checkFile('scripts/verify.sh');
|
|
177
187
|
checkFile('scripts/pack-template.sh');
|
|
188
|
+
checkFile('scripts/prepublish-guard.js');
|
|
178
189
|
checkFile('bin/multimodel-dev-os.js');
|
|
179
190
|
|
|
180
191
|
// --- GitHub Integration ---
|
|
@@ -204,6 +215,34 @@ checkFile('docs/release-policy.md');
|
|
|
204
215
|
checkFile('docs/support-policy.md');
|
|
205
216
|
checkFile('docs/final-launch.md');
|
|
206
217
|
checkFile('docs/v1-checklist.md');
|
|
218
|
+
checkFile('docs/model-compatibility.md');
|
|
219
|
+
checkFile('docs/model-routing.md');
|
|
220
|
+
checkFile('docs/local-models.md');
|
|
221
|
+
checkFile('docs/provider-strategy.md');
|
|
222
|
+
checkFile('docs/agent-compatibility.md');
|
|
223
|
+
checkFile('docs/adapter-authoring.md');
|
|
224
|
+
checkFile('docs/token-optimization.md');
|
|
225
|
+
checkFile('docs/mobile-android.md');
|
|
226
|
+
checkFile('docs/v2-roadmap.md');
|
|
227
|
+
checkFile('docs/template-authoring.md');
|
|
228
|
+
checkFile('docs/skill-authoring.md');
|
|
229
|
+
checkFile('docs/registry-contribution.md');
|
|
230
|
+
checkFile('docs/v2-migration.md');
|
|
231
|
+
checkFile('docs/v2-release-checklist.md');
|
|
232
|
+
checkFile('docs/package-safety.md');
|
|
233
|
+
|
|
234
|
+
// --- Model & Adapter Registries ---
|
|
235
|
+
console.log('\nModel & Adapter Registries:');
|
|
236
|
+
checkFile('.ai/models/registry.yaml');
|
|
237
|
+
checkFile('.ai/models/providers.yaml');
|
|
238
|
+
checkFile('.ai/models/routing-presets.yaml');
|
|
239
|
+
checkFile('.ai/models/local-models.yaml');
|
|
240
|
+
checkFile('.ai/models/README.md');
|
|
241
|
+
checkFile('.ai/adapters/registry.yaml');
|
|
242
|
+
checkFile('.ai/templates/registry.yaml');
|
|
243
|
+
checkFile('.ai/templates/custom-template.example.yaml');
|
|
244
|
+
checkFile('.ai/adapters/custom-adapter.example.yaml');
|
|
245
|
+
checkFile('.ai/skills/custom-skill.example.md');
|
|
207
246
|
|
|
208
247
|
// --- JSON Schemas ---
|
|
209
248
|
console.log('\nJSON Schemas:');
|
|
@@ -215,7 +254,10 @@ checkFile('.ai/schema/adapter.schema.json');
|
|
|
215
254
|
console.log('\nTest Manuals:');
|
|
216
255
|
checkFile('tests/README.md');
|
|
217
256
|
checkFile('tests/fixtures/README.md');
|
|
257
|
+
checkFile('tests/fixtures/custom-template-example/README.md');
|
|
258
|
+
checkFile('tests/fixtures/registry-overrides/README.md');
|
|
218
259
|
checkFile('tests/smoke/README.md');
|
|
260
|
+
checkFile('tests/smoke/cli-smoke.md');
|
|
219
261
|
|
|
220
262
|
// --- Visual & AI Discovery Assets ---
|
|
221
263
|
console.log('\nVisual & AI Discovery Assets:');
|
|
@@ -231,6 +273,111 @@ checkFile('docs/public/assets/social-preview.svg');
|
|
|
231
273
|
checkFile('docs/public/assets/terminal-demo.svg');
|
|
232
274
|
checkFile('docs/public/assets/architecture-preview.svg');
|
|
233
275
|
|
|
276
|
+
// --- YAML Parser Helper ---
|
|
277
|
+
function parseYaml(content) {
|
|
278
|
+
try {
|
|
279
|
+
const root = {};
|
|
280
|
+
const stack = [{ obj: root, indent: -1, key: null, isArray: false }];
|
|
281
|
+
const lines = content.split(/\r?\n/);
|
|
282
|
+
for (let line of lines) {
|
|
283
|
+
const commentIdx = line.indexOf('#');
|
|
284
|
+
if (commentIdx !== -1) {
|
|
285
|
+
line = line.substring(0, commentIdx);
|
|
286
|
+
}
|
|
287
|
+
line = line.trimEnd();
|
|
288
|
+
if (!line.trim()) continue;
|
|
289
|
+
const indent = line.match(/^ */)[0].length;
|
|
290
|
+
let trimmed = line.trim();
|
|
291
|
+
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
292
|
+
stack.pop();
|
|
293
|
+
}
|
|
294
|
+
const parent = stack[stack.length - 1];
|
|
295
|
+
if (trimmed.startsWith('-')) {
|
|
296
|
+
trimmed = trimmed.substring(1).trim();
|
|
297
|
+
if (!Array.isArray(parent.obj)) {
|
|
298
|
+
const grandparent = stack[stack.length - 2];
|
|
299
|
+
if (grandparent) {
|
|
300
|
+
grandparent.obj[parent.key] = [];
|
|
301
|
+
parent.obj = grandparent.obj[parent.key];
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const colonIdx = trimmed.indexOf(':');
|
|
305
|
+
if (colonIdx === -1) {
|
|
306
|
+
parent.obj.push(trimmed);
|
|
307
|
+
} else {
|
|
308
|
+
const key = trimmed.substring(0, colonIdx).trim();
|
|
309
|
+
let val = trimmed.substring(colonIdx + 1).trim();
|
|
310
|
+
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
|
|
311
|
+
val = val.substring(1, val.length - 1);
|
|
312
|
+
}
|
|
313
|
+
if (val === 'true') val = true;
|
|
314
|
+
else if (val === 'false') val = false;
|
|
315
|
+
else if (val === 'null') val = null;
|
|
316
|
+
else if (/^\d+$/.test(val)) val = parseInt(val, 10);
|
|
317
|
+
const newObj = { [key]: val };
|
|
318
|
+
parent.obj.push(newObj);
|
|
319
|
+
stack.push({ obj: newObj, indent: indent, key: key, isArray: false });
|
|
320
|
+
}
|
|
321
|
+
} else {
|
|
322
|
+
const colonIdx = trimmed.indexOf(':');
|
|
323
|
+
if (colonIdx === -1) continue;
|
|
324
|
+
const key = trimmed.substring(0, colonIdx).trim();
|
|
325
|
+
let val = trimmed.substring(colonIdx + 1).trim();
|
|
326
|
+
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
|
|
327
|
+
val = val.substring(1, val.length - 1);
|
|
328
|
+
}
|
|
329
|
+
if (val === 'true') val = true;
|
|
330
|
+
else if (val === 'false') val = false;
|
|
331
|
+
else if (val === 'null') val = null;
|
|
332
|
+
else if (/^\d+$/.test(val)) val = parseInt(val, 10);
|
|
333
|
+
if (val === '') {
|
|
334
|
+
parent.obj[key] = {};
|
|
335
|
+
stack.push({ obj: parent.obj[key], indent: indent, key: key, isArray: false });
|
|
336
|
+
} else {
|
|
337
|
+
parent.obj[key] = val;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return root;
|
|
342
|
+
} catch (e) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function verifyRegistryParsed(relPath, requiredRootKey) {
|
|
348
|
+
const fullPath = join(projectRoot, relPath);
|
|
349
|
+
if (!existsSync(fullPath)) {
|
|
350
|
+
console.error(` ${RED}✗${NC} ${relPath} (missing for parsing)`);
|
|
351
|
+
fail++;
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
const data = parseYaml(readFileSync(fullPath, 'utf8'));
|
|
356
|
+
if (!data || typeof data !== 'object') {
|
|
357
|
+
console.error(` ${RED}✗${NC} ${relPath} (YAML parsing returned invalid object)`);
|
|
358
|
+
fail++;
|
|
359
|
+
} else if (requiredRootKey && !data[requiredRootKey]) {
|
|
360
|
+
console.error(` ${RED}✗${NC} ${relPath} (missing root key: "${requiredRootKey}")`);
|
|
361
|
+
fail++;
|
|
362
|
+
} else {
|
|
363
|
+
console.log(` ${GREEN}✓${NC} ${relPath} (parsed successfully, verified root key "${requiredRootKey}")`);
|
|
364
|
+
pass++;
|
|
365
|
+
}
|
|
366
|
+
} catch (e) {
|
|
367
|
+
console.error(` ${RED}✗${NC} ${relPath} (failed parsing: ${e.message})`);
|
|
368
|
+
fail++;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// --- Verifying Registry Parsers and Syntax Sanity ---
|
|
373
|
+
console.log('\nVerifying Registry Parsers and Syntax Sanity:');
|
|
374
|
+
verifyRegistryParsed('.ai/models/registry.yaml', 'models');
|
|
375
|
+
verifyRegistryParsed('.ai/models/providers.yaml', 'providers');
|
|
376
|
+
verifyRegistryParsed('.ai/models/routing-presets.yaml', 'presets');
|
|
377
|
+
verifyRegistryParsed('.ai/models/local-models.yaml', 'local_engines');
|
|
378
|
+
verifyRegistryParsed('.ai/adapters/registry.yaml', 'adapters');
|
|
379
|
+
verifyRegistryParsed('.ai/templates/registry.yaml', 'templates');
|
|
380
|
+
|
|
234
381
|
// --- CLI & Packaging Pre-Flight Tests ---
|
|
235
382
|
console.log('\nRunning CLI & Packaging Pre-Flight Tests...');
|
|
236
383
|
|
|
@@ -298,6 +445,36 @@ try {
|
|
|
298
445
|
fail++;
|
|
299
446
|
}
|
|
300
447
|
|
|
448
|
+
// --- Package Safety & Hygiene Checks ---
|
|
449
|
+
console.log('\nPackage Safety & Hygiene Checks:');
|
|
450
|
+
if (existsSync(join(projectRoot, '.npmrc'))) {
|
|
451
|
+
console.error(` ${RED}✗ .npmrc file exists in package root (security risk)${NC}`);
|
|
452
|
+
fail++;
|
|
453
|
+
} else {
|
|
454
|
+
console.log(` ${GREEN}✓${NC} No .npmrc file present in package root`);
|
|
455
|
+
pass++;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const checkExamplesHygiene = (dir) => {
|
|
459
|
+
if (!existsSync(dir)) return;
|
|
460
|
+
const items = readdirSync(dir);
|
|
461
|
+
for (const item of items) {
|
|
462
|
+
const fullPath = join(dir, item);
|
|
463
|
+
try {
|
|
464
|
+
const stat = statSync(fullPath);
|
|
465
|
+
if (stat.isDirectory()) {
|
|
466
|
+
checkExamplesHygiene(fullPath);
|
|
467
|
+
} else if (stat.isFile()) {
|
|
468
|
+
if (item === '.env' || item.endsWith('.keystore') || item.endsWith('.jks')) {
|
|
469
|
+
console.error(` ${RED}✗ Unsafe file found inside examples: ${fullPath.replace(projectRoot, '')}${NC}`);
|
|
470
|
+
fail++;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
} catch (e) {}
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
checkExamplesHygiene(join(projectRoot, 'examples'));
|
|
477
|
+
|
|
301
478
|
console.log('\n=====================================================');
|
|
302
479
|
const total = pass + fail + warn;
|
|
303
480
|
console.log(` Pass: ${GREEN}${pass}${NC} Fail: ${RED}${fail}${NC} Warn: ${YELLOW}${warn}${NC} Total: ${total}`);
|