delimit-cli 4.1.32 → 4.1.34
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 +1 -0
- package/bin/delimit-cli.js +81 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,6 +31,7 @@ Works across any configuration — from a single model on a budget to an enterpr
|
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
npx delimit-cli scan # Instant health grade for your API spec
|
|
34
|
+
npx delimit-cli try owner/repo # Try governance on any GitHub repo
|
|
34
35
|
npx delimit-cli pr owner/repo#123 # Review any GitHub PR for breaking changes
|
|
35
36
|
npx delimit-cli setup && source ~/.bashrc # Configure AI assistants + activate
|
|
36
37
|
```
|
package/bin/delimit-cli.js
CHANGED
|
@@ -2540,8 +2540,44 @@ program
|
|
|
2540
2540
|
console.log(chalk.gray(' Tip: point at a spec file: npx delimit-cli scan openapi.yaml'));
|
|
2541
2541
|
}
|
|
2542
2542
|
}
|
|
2543
|
+
// Governance readiness checklist
|
|
2544
|
+
const hasPolicy = fs.existsSync(path.join(target, '.delimit', 'policies.yml'));
|
|
2545
|
+
const hasWorkflow = fs.existsSync(path.join(target, '.github', 'workflows', 'api-governance.yml'));
|
|
2546
|
+
const hasGitHooks = fs.existsSync(path.join(target, '.git', 'hooks', 'pre-commit')) &&
|
|
2547
|
+
(() => { try { return fs.readFileSync(path.join(target, '.git', 'hooks', 'pre-commit'), 'utf-8').includes('delimit'); } catch { return false; } })();
|
|
2548
|
+
const hasMcp = fs.existsSync(path.join(os.homedir(), '.mcp.json')) &&
|
|
2549
|
+
(() => { try { return fs.readFileSync(path.join(os.homedir(), '.mcp.json'), 'utf-8').includes('delimit'); } catch { return false; } })();
|
|
2550
|
+
const hasSpecs = found.length > 0;
|
|
2551
|
+
|
|
2552
|
+
const checks = [
|
|
2553
|
+
{ name: 'API spec', done: hasSpecs, fix: 'Add an openapi.yaml to your project' },
|
|
2554
|
+
{ name: 'Policy', done: hasPolicy, fix: 'npx delimit-cli init' },
|
|
2555
|
+
{ name: 'CI gate', done: hasWorkflow, fix: 'npx delimit-cli ci' },
|
|
2556
|
+
{ name: 'Git hooks', done: hasGitHooks, fix: 'npx delimit-cli hooks install' },
|
|
2557
|
+
{ name: 'MCP tools', done: hasMcp, fix: 'npx delimit-cli setup' },
|
|
2558
|
+
];
|
|
2559
|
+
const score = checks.filter(c => c.done).length;
|
|
2560
|
+
|
|
2561
|
+
console.log(chalk.bold(`\n Governance Readiness: ${score}/${checks.length}\n`));
|
|
2562
|
+
for (const c of checks) {
|
|
2563
|
+
if (c.done) {
|
|
2564
|
+
console.log(` ${chalk.green('●')} ${c.name}`);
|
|
2565
|
+
} else {
|
|
2566
|
+
console.log(` ${chalk.gray('○')} ${c.name} ${chalk.gray('—')} ${chalk.yellow(c.fix)}`);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
console.log('');
|
|
2570
|
+
|
|
2543
2571
|
// Interactive next step picker
|
|
2544
2572
|
try {
|
|
2573
|
+
// Pre-select the first missing item
|
|
2574
|
+
const firstMissing = checks.find(c => !c.done);
|
|
2575
|
+
const defaultChoice = firstMissing ?
|
|
2576
|
+
(firstMissing.name === 'Policy' ? 'init' :
|
|
2577
|
+
firstMissing.name === 'CI gate' ? 'ci' :
|
|
2578
|
+
firstMissing.name === 'Git hooks' ? 'hooks' :
|
|
2579
|
+
firstMissing.name === 'MCP tools' ? 'setup' : 'init') : 'exit';
|
|
2580
|
+
|
|
2545
2581
|
const { next } = await inquirer.prompt([{
|
|
2546
2582
|
type: 'list',
|
|
2547
2583
|
name: 'next',
|
|
@@ -2549,15 +2585,19 @@ program
|
|
|
2549
2585
|
choices: [
|
|
2550
2586
|
{ name: 'Set up governance for this project', value: 'init' },
|
|
2551
2587
|
{ name: 'Add CI gate (GitHub Action)', value: 'ci' },
|
|
2588
|
+
{ name: 'Install git hooks', value: 'hooks' },
|
|
2552
2589
|
{ name: 'Configure AI assistants (Claude, Codex, Gemini)', value: 'setup' },
|
|
2553
2590
|
{ name: 'Run a breaking change demo', value: 'try' },
|
|
2554
2591
|
{ name: 'Exit', value: 'exit' },
|
|
2555
2592
|
],
|
|
2593
|
+
default: defaultChoice,
|
|
2556
2594
|
}]);
|
|
2557
2595
|
if (next === 'init') {
|
|
2558
2596
|
execSync('npx delimit-cli init', { stdio: 'inherit' });
|
|
2559
2597
|
} else if (next === 'ci') {
|
|
2560
2598
|
execSync('npx delimit-cli ci', { stdio: 'inherit' });
|
|
2599
|
+
} else if (next === 'hooks') {
|
|
2600
|
+
execSync('npx delimit-cli hooks install', { stdio: 'inherit' });
|
|
2561
2601
|
} else if (next === 'setup') {
|
|
2562
2602
|
execSync('npx delimit-cli setup', { stdio: 'inherit' });
|
|
2563
2603
|
} else if (next === 'try') {
|
|
@@ -2747,15 +2787,52 @@ print(json.dumps({'changes':[{'type':c.type.value if hasattr(c.type,'value') els
|
|
|
2747
2787
|
}
|
|
2748
2788
|
});
|
|
2749
2789
|
|
|
2750
|
-
// Try command — zero-risk demo with Markdown report artifact (LED-264)
|
|
2790
|
+
// Try command — zero-risk demo with Markdown report artifact (LED-264 + LED-424)
|
|
2751
2791
|
program
|
|
2752
|
-
.command('try')
|
|
2753
|
-
.description('Run
|
|
2754
|
-
.action(async () => {
|
|
2792
|
+
.command('try [repo]')
|
|
2793
|
+
.description('Run governance on your project, a GitHub repo, or a built-in demo')
|
|
2794
|
+
.action(async (repo) => {
|
|
2755
2795
|
const tmpDir = path.join(os.tmpdir(), `delimit-try-${Date.now()}`);
|
|
2756
2796
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
2757
2797
|
|
|
2758
2798
|
console.log(chalk.bold('\n Delimit — Try It\n'));
|
|
2799
|
+
|
|
2800
|
+
// Mode 1: Clone a GitHub repo and scan it
|
|
2801
|
+
if (repo && (repo.includes('/') || repo.startsWith('http'))) {
|
|
2802
|
+
const repoUrl = repo.startsWith('http') ? repo : `https://github.com/${repo}`;
|
|
2803
|
+
console.log(chalk.gray(` Cloning ${repoUrl}...\n`));
|
|
2804
|
+
try {
|
|
2805
|
+
execSync(`git clone --depth 1 ${repoUrl} ${tmpDir}/repo 2>&1`, { timeout: 30000 });
|
|
2806
|
+
console.log(chalk.green(' Cloned. Scanning for OpenAPI specs...\n'));
|
|
2807
|
+
execSync(`node "${path.join(__dirname, 'delimit-cli.js')}" scan ${tmpDir}/repo`, { stdio: 'inherit', timeout: 30000 });
|
|
2808
|
+
// Show governance readiness for their repo
|
|
2809
|
+
console.log(chalk.bold('\n Want to add governance to this repo?\n'));
|
|
2810
|
+
console.log(` ${chalk.green('1.')} Fork it and run ${chalk.bold('npx delimit-cli init')}`);
|
|
2811
|
+
console.log(` ${chalk.green('2.')} Add CI: ${chalk.bold('npx delimit-cli ci')}`);
|
|
2812
|
+
console.log(` ${chalk.green('3.')} Open a PR — Delimit comments with breaking changes automatically\n`);
|
|
2813
|
+
try { fs.rmSync(tmpDir, { recursive: true }); } catch {}
|
|
2814
|
+
return;
|
|
2815
|
+
} catch (err) {
|
|
2816
|
+
console.log(chalk.red(` Could not clone: ${err.message}\n`));
|
|
2817
|
+
console.log(chalk.gray(' Falling back to built-in demo...\n'));
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
// Mode 2: Use current directory if it has specs
|
|
2822
|
+
if (!repo) {
|
|
2823
|
+
const cwd = process.cwd();
|
|
2824
|
+
const localSpecs = ['openapi.yaml', 'openapi.yml', 'openapi.json', 'swagger.yaml', 'swagger.json',
|
|
2825
|
+
'api/openapi.yaml', 'api/openapi.yml', 'api/openapi.json', 'spec/api.json', 'docs/openapi.yaml'];
|
|
2826
|
+
const foundLocal = localSpecs.find(s => fs.existsSync(path.join(cwd, s)));
|
|
2827
|
+
if (foundLocal) {
|
|
2828
|
+
console.log(chalk.green(` Found ${foundLocal} in current directory. Running governance scan...\n`));
|
|
2829
|
+
execSync(`node "${path.join(__dirname, 'delimit-cli.js')}" scan ${path.join(cwd, foundLocal)}`, { stdio: 'inherit', timeout: 30000 });
|
|
2830
|
+
try { fs.rmSync(tmpDir, { recursive: true }); } catch {}
|
|
2831
|
+
return;
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
// Mode 3: Built-in demo (original behavior)
|
|
2759
2836
|
console.log(chalk.gray(' Safe mode: runs in a temp directory, nothing touches your project.\n'));
|
|
2760
2837
|
|
|
2761
2838
|
// Create sample specs (same as demo)
|
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": "4.1.
|
|
4
|
+
"version": "4.1.34",
|
|
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": [
|