delimit-cli 3.14.0 → 3.14.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.
Files changed (2) hide show
  1. package/bin/delimit-cli.js +165 -0
  2. package/package.json +1 -1
@@ -5,6 +5,7 @@ const axios = require('axios');
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
7
  const { execSync, spawn } = require('child_process');
8
+ const os = require('os');
8
9
  const chalk = require('chalk');
9
10
  const inquirer = require('inquirer');
10
11
  const DelimitAuthSetup = require('../lib/auth-setup');
@@ -1334,6 +1335,170 @@ jobs:
1334
1335
  console.log('');
1335
1336
  });
1336
1337
 
1338
+ // Demo command — prove governance value in 5 minutes (LED-262)
1339
+ program
1340
+ .command('demo')
1341
+ .description('Run a self-contained governance demo — proves value in under 5 minutes')
1342
+ .action(async () => {
1343
+ const tmpDir = path.join(os.tmpdir(), `delimit-demo-${Date.now()}`);
1344
+ fs.mkdirSync(tmpDir, { recursive: true });
1345
+
1346
+ console.log(chalk.bold('\n Delimit Governance Demo\n'));
1347
+ console.log(chalk.gray(` Working in ${tmpDir}\n`));
1348
+
1349
+ // Step 1: Create a sample API spec
1350
+ console.log(chalk.bold(' Step 1: Creating sample API spec...'));
1351
+ const baseSpec = {
1352
+ openapi: '3.0.3',
1353
+ info: { title: 'Pet Store API', version: '1.0.0' },
1354
+ paths: {
1355
+ '/pets': {
1356
+ get: {
1357
+ summary: 'List all pets',
1358
+ operationId: 'listPets',
1359
+ parameters: [
1360
+ { name: 'limit', in: 'query', required: false, schema: { type: 'integer' } },
1361
+ ],
1362
+ responses: { '200': { description: 'A list of pets', content: { 'application/json': { schema: { type: 'array', items: { '$ref': '#/components/schemas/Pet' } } } } } },
1363
+ },
1364
+ post: {
1365
+ summary: 'Create a pet',
1366
+ operationId: 'createPet',
1367
+ requestBody: { content: { 'application/json': { schema: { '$ref': '#/components/schemas/Pet' } } } },
1368
+ responses: { '201': { description: 'Pet created' } },
1369
+ },
1370
+ },
1371
+ '/pets/{petId}': {
1372
+ get: {
1373
+ summary: 'Get a pet by ID',
1374
+ operationId: 'showPetById',
1375
+ parameters: [{ name: 'petId', in: 'path', required: true, schema: { type: 'string' } }],
1376
+ responses: { '200': { description: 'A pet', content: { 'application/json': { schema: { '$ref': '#/components/schemas/Pet' } } } } },
1377
+ },
1378
+ },
1379
+ },
1380
+ components: {
1381
+ schemas: {
1382
+ Pet: {
1383
+ type: 'object',
1384
+ required: ['id', 'name'],
1385
+ properties: {
1386
+ id: { type: 'integer', format: 'int64' },
1387
+ name: { type: 'string' },
1388
+ tag: { type: 'string' },
1389
+ },
1390
+ },
1391
+ },
1392
+ },
1393
+ };
1394
+
1395
+ const baseSpecPath = path.join(tmpDir, 'openapi-v1.yaml');
1396
+ fs.writeFileSync(baseSpecPath, yaml.dump(baseSpec));
1397
+ console.log(chalk.green(' Created openapi-v1.yaml (3 endpoints, 1 schema)\n'));
1398
+
1399
+ // Step 2: Introduce breaking changes
1400
+ console.log(chalk.bold(' Step 2: Introducing breaking changes...'));
1401
+ const changedSpec = JSON.parse(JSON.stringify(baseSpec));
1402
+ changedSpec.info.version = '2.0.0';
1403
+
1404
+ // Breaking: remove endpoint
1405
+ delete changedSpec.paths['/pets/{petId}'];
1406
+ // Breaking: add required parameter
1407
+ changedSpec.paths['/pets'].get.parameters.push(
1408
+ { name: 'owner_id', in: 'query', required: true, schema: { type: 'string' } }
1409
+ );
1410
+ // Breaking: remove response field
1411
+ delete changedSpec.components.schemas.Pet.properties.tag;
1412
+ // Non-breaking: add endpoint
1413
+ changedSpec.paths['/pets/search'] = {
1414
+ get: {
1415
+ summary: 'Search pets',
1416
+ operationId: 'searchPets',
1417
+ parameters: [{ name: 'q', in: 'query', required: true, schema: { type: 'string' } }],
1418
+ responses: { '200': { description: 'Search results' } },
1419
+ },
1420
+ };
1421
+
1422
+ const changedSpecPath = path.join(tmpDir, 'openapi-v2.yaml');
1423
+ fs.writeFileSync(changedSpecPath, yaml.dump(changedSpec));
1424
+ console.log(chalk.red(' Removed: GET /pets/{petId}'));
1425
+ console.log(chalk.red(' Added required param: owner_id on GET /pets'));
1426
+ console.log(chalk.red(' Removed field: Pet.tag'));
1427
+ console.log(chalk.green(' Added: GET /pets/search'));
1428
+ console.log('');
1429
+
1430
+ // Step 3: Run Delimit lint
1431
+ console.log(chalk.bold(' Step 3: Running governance check...\n'));
1432
+ try {
1433
+ const result = apiEngine.lint(baseSpecPath, changedSpecPath, { policy: 'strict' });
1434
+
1435
+ if (result && result.summary) {
1436
+ const s = result.summary;
1437
+ const breaking = s.breaking || s.breaking_changes || 0;
1438
+ const total = s.total || s.total_changes || 0;
1439
+ const safe = total - breaking;
1440
+
1441
+ if (breaking > 0) {
1442
+ console.log(chalk.red.bold(` BLOCKED — ${breaking} breaking change(s) detected\n`));
1443
+ } else {
1444
+ console.log(chalk.green.bold(` PASSED — No breaking changes\n`));
1445
+ }
1446
+
1447
+ // Show violations
1448
+ const violations = result.violations || [];
1449
+ if (violations.length > 0) {
1450
+ console.log(chalk.bold(' Violations:'));
1451
+ violations.forEach((v, i) => {
1452
+ const icon = v.severity === 'error' ? chalk.red(' BLOCK') : chalk.yellow(' WARN ');
1453
+ console.log(` ${icon} ${v.message}`);
1454
+ if (v.path) console.log(chalk.gray(` ${v.path}`));
1455
+ });
1456
+ console.log('');
1457
+ }
1458
+
1459
+ // Semver
1460
+ if (result.semver) {
1461
+ console.log(` Semver: ${chalk.bold(result.semver.bump?.toUpperCase() || 'MAJOR')}`);
1462
+ if (result.semver.next_version) {
1463
+ console.log(` Next version: ${chalk.bold(result.semver.next_version)}`);
1464
+ }
1465
+ }
1466
+
1467
+ // Show safe changes
1468
+ if (safe > 0) {
1469
+ console.log(chalk.green(`\n ${safe} additive change(s) also detected`));
1470
+ }
1471
+ }
1472
+ } catch (err) {
1473
+ console.log(chalk.yellow(` Lint error: ${err.message}`));
1474
+ }
1475
+
1476
+ // Step 4: Show governance gates
1477
+ console.log(chalk.bold('\n Governance Gates:'));
1478
+ console.log(` ${chalk.red('X')} API Lint ${chalk.gray('→ semver → gov_evaluate')}`);
1479
+ console.log(` ${chalk.red('X')} Policy Compliance ${chalk.gray('→ evidence_collect')}`);
1480
+ console.log(` ${chalk.green('+')} Security Audit ${chalk.gray('→ evidence_collect → notify')}`);
1481
+ console.log(` ${chalk.red('X')} Deploy Readiness ${chalk.gray('→ deploy_plan → security_audit')}`);
1482
+ console.log(chalk.red.bold('\n Deploy BLOCKED until all gates pass.\n'));
1483
+
1484
+ // Step 5: Show what would happen with the fix
1485
+ console.log(chalk.bold(' What Delimit does:'));
1486
+ console.log(chalk.gray(' 1. Detects the 3 breaking changes automatically'));
1487
+ console.log(chalk.gray(' 2. Evaluates against your policy (strict/default/relaxed)'));
1488
+ console.log(chalk.gray(' 3. Blocks the deploy via governance gates'));
1489
+ console.log(chalk.gray(' 4. Records evidence for audit trail'));
1490
+ console.log(chalk.gray(' 5. Posts remediation guide on the PR'));
1491
+ console.log(chalk.gray(' 6. Tracks in the ledger for cross-model continuity'));
1492
+
1493
+ console.log(chalk.bold('\n Try it on your project:'));
1494
+ console.log(` ${chalk.green('npx delimit-cli init')} — set up governance`);
1495
+ console.log(` ${chalk.green('npx delimit-cli lint')} — lint your API spec`);
1496
+ console.log(` ${chalk.green('npx delimit-cli setup')} — configure AI assistants\n`);
1497
+
1498
+ // Cleanup
1499
+ try { fs.rmSync(tmpDir, { recursive: true }); } catch {}
1500
+ });
1501
+
1337
1502
  // Doctor command — verify setup is correct
1338
1503
  program
1339
1504
  .command('doctor')
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "delimit-cli",
3
3
  "mcpName": "io.github.delimit-ai/delimit-mcp-server",
4
- "version": "3.14.0",
4
+ "version": "3.14.1",
5
5
  "description": "Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, governance, and multi-model debate.",
6
6
  "main": "index.js",
7
7
  "files": [