delimit-cli 3.14.2 → 3.14.3
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 +43 -25
- package/bin/delimit-cli.js +193 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# `</>` Delimit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
API governance that enforces itself. One workspace for Claude Code, Codex, Cursor, and Gemini CLI.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/delimit-cli)
|
|
6
|
-
[](https://github.com/marketplace/actions/delimit-api-governance)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
8
|
[](https://glama.ai/mcp/servers/delimit-ai/delimit-mcp-server)
|
|
9
9
|
[](https://github.com/marketplace/actions/delimit-api-governance)
|
|
@@ -12,13 +12,35 @@ Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, govern
|
|
|
12
12
|
<img src="docs/demo.gif" alt="Delimit detecting breaking API changes" width="700">
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Try it in 2 minutes
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx delimit-cli demo # See governance in action — no setup needed
|
|
21
|
+
npx delimit-cli init # Set up governance for your project
|
|
22
|
+
npx delimit-cli setup # Configure your AI assistants
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
No API keys. No account. No config files.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## What's New in v3.14
|
|
30
|
+
|
|
31
|
+
- **Evidence timeline + gate status dashboard** -- see every governance decision and when it happened
|
|
32
|
+
- **Multi-agent orchestration** -- track which AI assistant works on what, across models
|
|
33
|
+
- **Continuous drift monitoring** -- detect spec drift between deployments automatically
|
|
34
|
+
- **PR governance copilot** -- gate status posted directly in PR comments
|
|
35
|
+
- **Compliance templates** -- SOC2, PCI-DSS, and HIPAA presets out of the box
|
|
36
|
+
- **Beta capture in CLI** -- opt into early features from the command line
|
|
37
|
+
- **112+ MCP tools** -- governance, context, shipping, observability, and orchestration
|
|
16
38
|
|
|
17
39
|
---
|
|
18
40
|
|
|
19
41
|
## GitHub Action
|
|
20
42
|
|
|
21
|
-
Zero-config
|
|
43
|
+
Zero-config -- auto-detects your OpenAPI spec:
|
|
22
44
|
|
|
23
45
|
```yaml
|
|
24
46
|
- uses: delimit-ai/delimit-action@v1
|
|
@@ -44,14 +66,9 @@ jobs:
|
|
|
44
66
|
spec: api/openapi.yaml
|
|
45
67
|
```
|
|
46
68
|
|
|
47
|
-
That's it. Delimit auto-fetches the base branch spec, diffs it, and posts a PR comment with
|
|
48
|
-
|
|
49
|
-
- Breaking changes with severity badges
|
|
50
|
-
- Semver classification (major/minor/patch)
|
|
51
|
-
- Step-by-step migration guide
|
|
52
|
-
- Policy violations
|
|
69
|
+
That's it. Delimit auto-fetches the base branch spec, diffs it, and posts a PR comment with breaking changes, semver classification, migration guides, and governance gate results.
|
|
53
70
|
|
|
54
|
-
[View on GitHub Marketplace
|
|
71
|
+
[View on GitHub Marketplace](https://github.com/marketplace/actions/delimit-api-governance) | [See a live demo (23 breaking changes)](https://github.com/delimit-ai/delimit-action-demo/pull/2)
|
|
55
72
|
|
|
56
73
|
### Example PR comment
|
|
57
74
|
|
|
@@ -60,34 +77,34 @@ That's it. Delimit auto-fetches the base branch spec, diffs it, and posts a PR c
|
|
|
60
77
|
> | Change | Path | Severity |
|
|
61
78
|
> |--------|------|----------|
|
|
62
79
|
> | endpoint_removed | `DELETE /pets/{petId}` | error |
|
|
63
|
-
> | type_changed | `/pets:GET:200[].id` (string
|
|
80
|
+
> | type_changed | `/pets:GET:200[].id` (string -> integer) | warning |
|
|
64
81
|
> | enum_value_removed | `/pets:GET:200[].status` | warning |
|
|
65
82
|
>
|
|
66
|
-
> **Semver**: MAJOR (1.0.0
|
|
83
|
+
> **Semver**: MAJOR (1.0.0 -> 2.0.0)
|
|
67
84
|
>
|
|
68
85
|
> **Migration Guide**: 3 steps to update your integration
|
|
86
|
+
>
|
|
87
|
+
> ### Governance Gates
|
|
88
|
+
> | Gate | Status | Chain |
|
|
89
|
+
> |------|--------|-------|
|
|
90
|
+
> | API Lint | Pass/Fail | lint -> semver -> gov_evaluate |
|
|
91
|
+
> | Policy Compliance | Pass/Fail | policy -> evidence_collect |
|
|
92
|
+
> | Security Audit | Pass | security_audit -> evidence_collect |
|
|
93
|
+
> | Deploy Readiness | Ready/Blocked | deploy_plan -> security_audit |
|
|
69
94
|
|
|
70
95
|
---
|
|
71
96
|
|
|
72
|
-
## CLI
|
|
73
|
-
|
|
74
|
-
Governance tools for AI coding assistants (Claude Code, Codex, Cursor, Gemini CLI):
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
npx delimit-cli setup
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
No API keys. No account. Installs in 10 seconds.
|
|
81
|
-
|
|
82
|
-
### CLI commands (all free)
|
|
97
|
+
## CLI commands
|
|
83
98
|
|
|
84
99
|
```bash
|
|
100
|
+
npx delimit-cli demo # Self-contained governance demo
|
|
101
|
+
npx delimit-cli init # Guided wizard with compliance templates
|
|
102
|
+
npx delimit-cli init --preset strict # Initialize with strict policy
|
|
85
103
|
npx delimit-cli setup # Install into all AI assistants
|
|
86
104
|
npx delimit-cli setup --dry-run # Preview changes first
|
|
87
105
|
npx delimit-cli lint api/openapi.yaml # Check for breaking changes
|
|
88
106
|
npx delimit-cli diff old.yaml new.yaml # Compare two specs
|
|
89
107
|
npx delimit-cli explain old.yaml new.yaml # Generate migration guide
|
|
90
|
-
npx delimit-cli init --preset strict # Initialize policies
|
|
91
108
|
npx delimit-cli doctor # Check setup health
|
|
92
109
|
npx delimit-cli uninstall --dry-run # Preview removal
|
|
93
110
|
```
|
|
@@ -194,6 +211,7 @@ rules:
|
|
|
194
211
|
## Links
|
|
195
212
|
|
|
196
213
|
- [delimit.ai](https://delimit.ai) -- homepage
|
|
214
|
+
- [Dashboard](https://app.delimit.ai) -- governance console
|
|
197
215
|
- [Docs](https://delimit.ai/docs) -- full documentation
|
|
198
216
|
- [GitHub Action](https://github.com/marketplace/actions/delimit-api-governance) -- Marketplace listing
|
|
199
217
|
- [Quickstart](https://github.com/delimit-ai/delimit-mcp-server) -- try it in 2 minutes
|
package/bin/delimit-cli.js
CHANGED
|
@@ -1538,6 +1538,163 @@ program
|
|
|
1538
1538
|
try { fs.rmSync(tmpDir, { recursive: true }); } catch {}
|
|
1539
1539
|
});
|
|
1540
1540
|
|
|
1541
|
+
// Try command — zero-risk demo with Markdown report artifact (LED-264)
|
|
1542
|
+
program
|
|
1543
|
+
.command('try')
|
|
1544
|
+
.description('Run a zero-risk governance demo and save a Markdown report')
|
|
1545
|
+
.action(async () => {
|
|
1546
|
+
const tmpDir = path.join(os.tmpdir(), `delimit-try-${Date.now()}`);
|
|
1547
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
1548
|
+
|
|
1549
|
+
console.log(chalk.bold('\n Delimit — Try It\n'));
|
|
1550
|
+
console.log(chalk.gray(' Safe mode: runs in a temp directory, nothing touches your project.\n'));
|
|
1551
|
+
|
|
1552
|
+
// Create sample specs (same as demo)
|
|
1553
|
+
const baseSpec = {
|
|
1554
|
+
openapi: '3.0.3',
|
|
1555
|
+
info: { title: 'Pet Store API', version: '1.0.0' },
|
|
1556
|
+
paths: {
|
|
1557
|
+
'/pets': {
|
|
1558
|
+
get: { summary: 'List all pets', parameters: [{ name: 'limit', in: 'query', required: false, schema: { type: 'integer' } }], responses: { '200': { description: 'A list of pets' } } },
|
|
1559
|
+
post: { summary: 'Create a pet', responses: { '201': { description: 'Pet created' } } },
|
|
1560
|
+
},
|
|
1561
|
+
'/pets/{petId}': {
|
|
1562
|
+
get: { summary: 'Get a pet by ID', parameters: [{ name: 'petId', in: 'path', required: true, schema: { type: 'string' } }], responses: { '200': { description: 'A pet' } } },
|
|
1563
|
+
},
|
|
1564
|
+
},
|
|
1565
|
+
components: { schemas: { Pet: { type: 'object', required: ['id', 'name'], properties: { id: { type: 'integer' }, name: { type: 'string' }, tag: { type: 'string' } } } } },
|
|
1566
|
+
};
|
|
1567
|
+
|
|
1568
|
+
const changedSpec = JSON.parse(JSON.stringify(baseSpec));
|
|
1569
|
+
changedSpec.info.version = '2.0.0';
|
|
1570
|
+
delete changedSpec.paths['/pets/{petId}'];
|
|
1571
|
+
changedSpec.paths['/pets'].get.parameters.push({ name: 'owner_id', in: 'query', required: true, schema: { type: 'string' } });
|
|
1572
|
+
delete changedSpec.components.schemas.Pet.properties.tag;
|
|
1573
|
+
changedSpec.paths['/pets/search'] = { get: { summary: 'Search pets', responses: { '200': { description: 'Search results' } } } };
|
|
1574
|
+
|
|
1575
|
+
const basePath = path.join(tmpDir, 'openapi-v1.yaml');
|
|
1576
|
+
const changedPath = path.join(tmpDir, 'openapi-v2.yaml');
|
|
1577
|
+
fs.writeFileSync(basePath, yaml.dump(baseSpec));
|
|
1578
|
+
fs.writeFileSync(changedPath, yaml.dump(changedSpec));
|
|
1579
|
+
|
|
1580
|
+
console.log(chalk.gray(' Running governance pipeline...\n'));
|
|
1581
|
+
|
|
1582
|
+
// Run lint
|
|
1583
|
+
let report = [];
|
|
1584
|
+
let violations = [];
|
|
1585
|
+
let semverBump = 'MAJOR';
|
|
1586
|
+
try {
|
|
1587
|
+
const result = apiEngine.lint(basePath, changedPath, { policy: 'strict' });
|
|
1588
|
+
if (result) {
|
|
1589
|
+
violations = result.violations || [];
|
|
1590
|
+
const s = result.summary || {};
|
|
1591
|
+
const breaking = s.breaking || s.breaking_changes || 0;
|
|
1592
|
+
const total = s.total || s.total_changes || 0;
|
|
1593
|
+
semverBump = result.semver?.bump?.toUpperCase() || 'MAJOR';
|
|
1594
|
+
|
|
1595
|
+
report.push('# Delimit Governance Report');
|
|
1596
|
+
report.push('');
|
|
1597
|
+
report.push(`**Generated**: ${new Date().toISOString().slice(0, 19).replace('T', ' ')} UTC`);
|
|
1598
|
+
report.push(`**API**: Pet Store API`);
|
|
1599
|
+
report.push(`**Changes**: ${total} total (${breaking} breaking)`);
|
|
1600
|
+
report.push(`**Semver**: ${semverBump}`);
|
|
1601
|
+
report.push('');
|
|
1602
|
+
report.push('## Governance Gates');
|
|
1603
|
+
report.push('');
|
|
1604
|
+
report.push('| Gate | Status | Enforcement Chain |');
|
|
1605
|
+
report.push('|------|--------|-------------------|');
|
|
1606
|
+
report.push(`| API Lint | ${breaking > 0 ? 'FAIL' : 'PASS'} | lint → semver → gov_evaluate |`);
|
|
1607
|
+
report.push(`| Policy Compliance | ${violations.length > 0 ? 'FAIL (' + violations.length + ')' : 'PASS'} | policy → evidence_collect |`);
|
|
1608
|
+
report.push('| Security Audit | PASS | security_audit → evidence_collect |');
|
|
1609
|
+
report.push(`| Deploy Readiness | ${breaking > 0 ? 'BLOCKED' : 'READY'} | deploy_plan → security_audit |`);
|
|
1610
|
+
report.push('');
|
|
1611
|
+
|
|
1612
|
+
if (violations.length > 0) {
|
|
1613
|
+
report.push('## Violations');
|
|
1614
|
+
report.push('');
|
|
1615
|
+
report.push('| Severity | Change | Location |');
|
|
1616
|
+
report.push('|----------|--------|----------|');
|
|
1617
|
+
violations.forEach(v => {
|
|
1618
|
+
report.push(`| ${v.severity === 'error' ? 'BLOCK' : 'WARN'} | ${v.message} | \`${v.path || ''}\` |`);
|
|
1619
|
+
});
|
|
1620
|
+
report.push('');
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
report.push('## What Delimit Does');
|
|
1624
|
+
report.push('');
|
|
1625
|
+
report.push('1. Detects breaking changes automatically (27 types)');
|
|
1626
|
+
report.push('2. Evaluates against your policy (strict/default/relaxed)');
|
|
1627
|
+
report.push('3. Blocks deploys via governance gates');
|
|
1628
|
+
report.push('4. Records evidence for audit trail');
|
|
1629
|
+
report.push('5. Posts remediation guide on PRs');
|
|
1630
|
+
report.push('6. Tracks in ledger for cross-model continuity');
|
|
1631
|
+
report.push('');
|
|
1632
|
+
report.push('## Get Started');
|
|
1633
|
+
report.push('');
|
|
1634
|
+
report.push('```bash');
|
|
1635
|
+
report.push('npx delimit-cli init # Set up governance');
|
|
1636
|
+
report.push('npx delimit-cli setup # Configure AI assistants');
|
|
1637
|
+
report.push('```');
|
|
1638
|
+
report.push('');
|
|
1639
|
+
report.push('---');
|
|
1640
|
+
report.push('[delimit.ai](https://delimit.ai) | [Dashboard](https://app.delimit.ai) | [GitHub](https://github.com/delimit-ai/delimit-mcp-server)');
|
|
1641
|
+
}
|
|
1642
|
+
} catch (err) {
|
|
1643
|
+
report.push('# Delimit Governance Report');
|
|
1644
|
+
report.push('');
|
|
1645
|
+
report.push(`Error: ${err.message}`);
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
// Save report to user's current directory
|
|
1649
|
+
const reportPath = path.join(process.cwd(), 'delimit-report.md');
|
|
1650
|
+
const reportContent = report.join('\n');
|
|
1651
|
+
fs.writeFileSync(reportPath, reportContent);
|
|
1652
|
+
|
|
1653
|
+
// Show summary in terminal
|
|
1654
|
+
const breakingCount = violations.filter(v => v.severity === 'error').length;
|
|
1655
|
+
if (breakingCount > 0) {
|
|
1656
|
+
console.log(chalk.red.bold(` BLOCKED — ${breakingCount} breaking change(s) detected`));
|
|
1657
|
+
}
|
|
1658
|
+
violations.forEach(v => {
|
|
1659
|
+
const icon = v.severity === 'error' ? chalk.red(' BLOCK') : chalk.yellow(' WARN ');
|
|
1660
|
+
console.log(` ${icon} ${v.message}`);
|
|
1661
|
+
});
|
|
1662
|
+
console.log('');
|
|
1663
|
+
console.log(chalk.bold(' Governance Gates:'));
|
|
1664
|
+
console.log(` ${breakingCount > 0 ? chalk.red('X') : chalk.green('+')} API Lint ${chalk.gray('→ semver → gov_evaluate')}`);
|
|
1665
|
+
console.log(` ${violations.length > 0 ? chalk.red('X') : chalk.green('+')} Policy Compliance ${chalk.gray('→ evidence_collect')}`);
|
|
1666
|
+
console.log(` ${chalk.green('+')} Security Audit ${chalk.gray('→ evidence_collect → notify')}`);
|
|
1667
|
+
console.log(` ${breakingCount > 0 ? chalk.red('X') : chalk.green('+')} Deploy Readiness ${chalk.gray('→ deploy_plan → security_audit')}`);
|
|
1668
|
+
console.log('');
|
|
1669
|
+
console.log(chalk.green.bold(` Report saved to: ${reportPath}`));
|
|
1670
|
+
console.log(chalk.gray(' Open it to see the full governance analysis.\n'));
|
|
1671
|
+
|
|
1672
|
+
console.log(chalk.bold(' Next:'));
|
|
1673
|
+
console.log(` ${chalk.green('npx delimit-cli init')} — set up governance in your project`);
|
|
1674
|
+
console.log(` ${chalk.green('npx delimit-cli setup')} — configure AI assistants`);
|
|
1675
|
+
console.log(chalk.gray(` rm delimit-report.md — clean up this report\n`));
|
|
1676
|
+
|
|
1677
|
+
// Beta capture
|
|
1678
|
+
try {
|
|
1679
|
+
const betaAns = await inquirer.prompt([{
|
|
1680
|
+
type: 'input',
|
|
1681
|
+
name: 'email',
|
|
1682
|
+
message: chalk.blue('Join the beta? Enter your email (or press Enter to skip):'),
|
|
1683
|
+
}]);
|
|
1684
|
+
if (betaAns.email && betaAns.email.includes('@')) {
|
|
1685
|
+
try {
|
|
1686
|
+
await axios.post('https://delimit.ai/api/subscribe', { email: betaAns.email, source: 'cli-try' });
|
|
1687
|
+
console.log(chalk.green('\n Thanks! You\'re on the list.\n'));
|
|
1688
|
+
} catch {
|
|
1689
|
+
console.log(chalk.green('\n Thanks! Visit https://delimit.ai\n'));
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
} catch {}
|
|
1693
|
+
|
|
1694
|
+
// Cleanup temp
|
|
1695
|
+
try { fs.rmSync(tmpDir, { recursive: true }); } catch {}
|
|
1696
|
+
});
|
|
1697
|
+
|
|
1541
1698
|
// Doctor command — verify setup is correct
|
|
1542
1699
|
program
|
|
1543
1700
|
.command('doctor')
|
|
@@ -1631,11 +1788,46 @@ program
|
|
|
1631
1788
|
warn++;
|
|
1632
1789
|
}
|
|
1633
1790
|
|
|
1791
|
+
// Preview what init would create (LED-265)
|
|
1792
|
+
const delimitDir = path.join(process.cwd(), '.delimit');
|
|
1793
|
+
const hasDelimitDir = fs.existsSync(delimitDir);
|
|
1794
|
+
console.log(chalk.bold('\n Init Preview:'));
|
|
1795
|
+
if (hasDelimitDir) {
|
|
1796
|
+
const files = [];
|
|
1797
|
+
try {
|
|
1798
|
+
const walk = (dir, prefix) => {
|
|
1799
|
+
for (const f of fs.readdirSync(dir)) {
|
|
1800
|
+
const full = path.join(dir, f);
|
|
1801
|
+
const rel = prefix ? `${prefix}/${f}` : f;
|
|
1802
|
+
if (fs.statSync(full).isDirectory()) walk(full, rel);
|
|
1803
|
+
else files.push(rel);
|
|
1804
|
+
}
|
|
1805
|
+
};
|
|
1806
|
+
walk(delimitDir, '.delimit');
|
|
1807
|
+
} catch {}
|
|
1808
|
+
console.log(chalk.green(` Already initialized — ${files.length} file(s) in .delimit/`));
|
|
1809
|
+
files.slice(0, 8).forEach(f => console.log(chalk.gray(` ${f}`)));
|
|
1810
|
+
if (files.length > 8) console.log(chalk.gray(` ... and ${files.length - 8} more`));
|
|
1811
|
+
} else {
|
|
1812
|
+
console.log(chalk.gray(' Running delimit init would create:'));
|
|
1813
|
+
console.log(chalk.gray(' .delimit/policies.yml — governance policy rules'));
|
|
1814
|
+
console.log(chalk.gray(' .delimit/evidence/ — audit trail events'));
|
|
1815
|
+
console.log(chalk.gray(' .delimit/compliance.json — if compliance template selected'));
|
|
1816
|
+
if (fs.existsSync(path.join(process.cwd(), '.github'))) {
|
|
1817
|
+
console.log(chalk.gray(' .github/workflows/api-governance.yml'));
|
|
1818
|
+
console.log(chalk.gray(' .github/workflows/api-drift-monitor.yml'));
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
// Undo instruction (LED-265)
|
|
1823
|
+
console.log(chalk.bold('\n Undo:'));
|
|
1824
|
+
console.log(chalk.gray(' rm -rf .delimit — remove all Delimit files'));
|
|
1825
|
+
console.log(chalk.gray(' delimit uninstall --dry-run — preview MCP removal\n'));
|
|
1826
|
+
|
|
1634
1827
|
// Summary
|
|
1635
1828
|
console.log('');
|
|
1636
1829
|
if (fail === 0 && warn === 0) {
|
|
1637
1830
|
console.log(chalk.green.bold(' All checks passed! Ready to lint.\n'));
|
|
1638
|
-
console.log('Keep Building.\n');
|
|
1639
1831
|
} else if (fail === 0) {
|
|
1640
1832
|
console.log(chalk.yellow.bold(` ${ok} passed, ${warn} warning(s). Setup looks good.\n`));
|
|
1641
1833
|
} else {
|
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.
|
|
4
|
+
"version": "3.14.3",
|
|
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": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"postinstall": "node scripts/postinstall.js",
|
|
24
|
-
"test": "node --test tests/setup-onboarding.test.js tests/setup-matrix.test.js tests/config-export-import.test.js tests/cross-model-hooks.test.js"
|
|
24
|
+
"test": "node --test tests/setup-onboarding.test.js tests/setup-matrix.test.js tests/config-export-import.test.js tests/cross-model-hooks.test.js tests/golden-path.test.js"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"openapi",
|