delimit-cli 3.11.9 → 3.11.11
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/CHANGELOG.md +48 -0
- package/README.md +9 -3
- package/adapters/codex-security.js +64 -0
- package/adapters/codex-skill.js +78 -0
- package/adapters/cursor-rules.js +97 -0
- package/bin/delimit-setup.js +14 -4
- package/package.json +2 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.11.10] - 2026-03-24
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Cursor adapter with `.cursor/rules/delimit.md` support (Cursor 0.45+)
|
|
7
|
+
- Codex adapters: `codex-skill.js` (governance) and `codex-security.js`
|
|
8
|
+
- Setup `--dry-run` previews config changes before writing
|
|
9
|
+
- Uninstall `--dry-run` with backups for all 4 AI assistants
|
|
10
|
+
- Post-install config validation (checks all assistant configs)
|
|
11
|
+
- npm publish workflow with provenance and approval gates
|
|
12
|
+
- Setup matrix tests (13 new tests across all AI assistants)
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Repo renamed to `delimit-ai/delimit-mcp-server`
|
|
16
|
+
- Description: "Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, governance, and multi-model debate."
|
|
17
|
+
- Clear Free vs Pro tier boundaries in README
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
- Hardened `.npmignore` (blocks .env, credentials, keys)
|
|
21
|
+
- Supply chain security section in SECURITY.md
|
|
22
|
+
|
|
23
|
+
## [3.11.9] - 2026-03-23
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Auto-detect API keys and CLIs on `delimit init` and `delimit version`
|
|
27
|
+
- `delimit_quickstart` MCP tool (60-second guided first-run)
|
|
28
|
+
- Deliberation cost tracking (estimate + actual per model)
|
|
29
|
+
- Input sanitization: `_sanitize_path`, `_sanitize_subprocess_arg`
|
|
30
|
+
- GitHub Action smoke test workflow
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- Gemini deliberation HTTP 400 (ADC credentials + jamsons project)
|
|
34
|
+
- Deliberation timeout: parallelized round 1 (46% faster)
|
|
35
|
+
- Sensor dedup: titles include repo/issue to prevent duplicates
|
|
36
|
+
- Test-mode guard prevents ledger pollution from tests
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Governance default mode: advisory -> guarded (blocks critical actions)
|
|
40
|
+
- Ledger tools now route through governance loop (113/116 tools)
|
|
41
|
+
- Dialogue deliberation capped at 4 rounds (was 6)
|
|
42
|
+
- Per-model API timeout: 120s -> 45s (fail fast)
|
|
43
|
+
|
|
44
|
+
## [3.11.8] - 2026-03-23
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
- Codex compatibility: 11 type coercion fixes (string->list/dict)
|
|
48
|
+
- CI green: FastMCP fallback, env var injection, mock patterns
|
|
49
|
+
- Dashboard dark/light mode with CSS variables
|
|
50
|
+
|
|
3
51
|
## [2.4.0] - 2026-03-15
|
|
4
52
|
|
|
5
53
|
### Added
|
package/README.md
CHANGED
|
@@ -5,15 +5,21 @@ Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, govern
|
|
|
5
5
|
[](https://www.npmjs.com/package/delimit-cli)
|
|
6
6
|
[](https://github.com/marketplace/actions/delimit-api-governance)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
|
-
[](https://glama.ai/mcp/servers/delimit-ai/delimit-mcp-server)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Persistent ledger, API governance, security orchestration, and multi-model deliberation — all shared across Claude Code, Codex, Cursor, and Gemini CLI.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
## GitHub Action
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Zero-config — auto-detects your OpenAPI spec:
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
- uses: delimit-ai/delimit-action@v1
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or with full configuration:
|
|
17
23
|
|
|
18
24
|
```yaml
|
|
19
25
|
name: API Contract Check
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Delimit Security Skill for Codex CLI
|
|
4
|
+
*
|
|
5
|
+
* Validates that Codex-generated code doesn't introduce security anti-patterns.
|
|
6
|
+
* Runs as a security validation skill.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const SECURITY_PATTERNS = [
|
|
13
|
+
{ pattern: /eval\s*\(/g, severity: 'high', message: 'eval() usage detected — potential code injection' },
|
|
14
|
+
{ pattern: /exec\s*\(/g, severity: 'medium', message: 'exec() usage — verify input sanitization' },
|
|
15
|
+
{ pattern: /shell\s*=\s*True/g, severity: 'high', message: 'subprocess with shell=True — command injection risk' },
|
|
16
|
+
{ pattern: /dangerouslySetInnerHTML/g, severity: 'medium', message: 'dangerouslySetInnerHTML — XSS risk' },
|
|
17
|
+
{ pattern: /password\s*=\s*["'][^"']+["']/gi, severity: 'high', message: 'Hardcoded password detected' },
|
|
18
|
+
{ pattern: /api[_-]?key\s*=\s*["'][A-Za-z0-9]{10,}["']/gi, severity: 'high', message: 'Hardcoded API key detected' },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
function checkSecurity(context) {
|
|
22
|
+
const code = context.code || context.content || '';
|
|
23
|
+
if (!code) return { status: 'clean', findings: [] };
|
|
24
|
+
|
|
25
|
+
const findings = [];
|
|
26
|
+
for (const { pattern, severity, message } of SECURITY_PATTERNS) {
|
|
27
|
+
const matches = code.match(pattern);
|
|
28
|
+
if (matches) {
|
|
29
|
+
findings.push({ severity, message, count: matches.length });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Audit
|
|
34
|
+
try {
|
|
35
|
+
const auditDir = path.join(process.env.HOME || '', '.delimit', 'audit');
|
|
36
|
+
fs.mkdirSync(auditDir, { recursive: true });
|
|
37
|
+
const record = {
|
|
38
|
+
timestamp: new Date().toISOString(),
|
|
39
|
+
source: 'codex-security',
|
|
40
|
+
findings_count: findings.length,
|
|
41
|
+
high_count: findings.filter(f => f.severity === 'high').length,
|
|
42
|
+
};
|
|
43
|
+
const auditFile = path.join(auditDir, `${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
44
|
+
fs.appendFileSync(auditFile, JSON.stringify(record) + '\n');
|
|
45
|
+
} catch {}
|
|
46
|
+
|
|
47
|
+
const hasHigh = findings.some(f => f.severity === 'high');
|
|
48
|
+
return {
|
|
49
|
+
status: hasHigh ? 'flagged' : findings.length > 0 ? 'warnings' : 'clean',
|
|
50
|
+
findings,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const context = process.argv[2] ? JSON.parse(process.argv[2]) : {};
|
|
55
|
+
const result = checkSecurity(context);
|
|
56
|
+
|
|
57
|
+
if (result.status === 'flagged') {
|
|
58
|
+
for (const f of result.findings) {
|
|
59
|
+
console.error(`[Delimit Security] ${f.severity.toUpperCase()}: ${f.message}`);
|
|
60
|
+
}
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
process.exit(0);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Delimit Governance Skill for Codex CLI
|
|
4
|
+
*
|
|
5
|
+
* Runs as a validation skill triggered on pre-code-generation and pre-suggestion.
|
|
6
|
+
* Checks governance state and policy compliance before Codex executes actions.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const DELIMIT_HOME = path.join(process.env.HOME || '', '.delimit');
|
|
13
|
+
const MODE_FILE = path.join(DELIMIT_HOME, 'enforcement_mode');
|
|
14
|
+
|
|
15
|
+
function getMode() {
|
|
16
|
+
try {
|
|
17
|
+
return fs.readFileSync(MODE_FILE, 'utf-8').trim();
|
|
18
|
+
} catch {
|
|
19
|
+
return 'guarded'; // Default
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function checkGovernance(context) {
|
|
24
|
+
const mode = getMode();
|
|
25
|
+
const warnings = [];
|
|
26
|
+
|
|
27
|
+
// Check if governance is initialized
|
|
28
|
+
const policiesFile = path.join(process.cwd(), '.delimit', 'policies.yml');
|
|
29
|
+
if (!fs.existsSync(policiesFile)) {
|
|
30
|
+
warnings.push('No .delimit/policies.yml — run: delimit init');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check for sensitive file access
|
|
34
|
+
const sensitivePatterns = ['.env', 'credentials', '.ssh', 'secrets'];
|
|
35
|
+
const target = context.target || context.file || '';
|
|
36
|
+
for (const pattern of sensitivePatterns) {
|
|
37
|
+
if (target.includes(pattern)) {
|
|
38
|
+
if (mode === 'enforce') {
|
|
39
|
+
return { status: 'blocked', reason: `Access to sensitive path: ${target}` };
|
|
40
|
+
}
|
|
41
|
+
warnings.push(`Accessing sensitive path: ${target}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Audit log
|
|
46
|
+
try {
|
|
47
|
+
const auditDir = path.join(DELIMIT_HOME, 'audit');
|
|
48
|
+
fs.mkdirSync(auditDir, { recursive: true });
|
|
49
|
+
const record = {
|
|
50
|
+
timestamp: new Date().toISOString(),
|
|
51
|
+
source: 'codex-skill',
|
|
52
|
+
mode,
|
|
53
|
+
context: typeof context === 'object' ? JSON.stringify(context).slice(0, 200) : String(context).slice(0, 200),
|
|
54
|
+
warnings,
|
|
55
|
+
};
|
|
56
|
+
const auditFile = path.join(auditDir, `${new Date().toISOString().split('T')[0]}.jsonl`);
|
|
57
|
+
fs.appendFileSync(auditFile, JSON.stringify(record) + '\n');
|
|
58
|
+
} catch {}
|
|
59
|
+
|
|
60
|
+
return { status: 'allowed', mode, warnings };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Entry point — read context from stdin or args
|
|
64
|
+
const context = process.argv[2] ? JSON.parse(process.argv[2]) : {};
|
|
65
|
+
const result = checkGovernance(context);
|
|
66
|
+
|
|
67
|
+
if (result.status === 'blocked') {
|
|
68
|
+
console.error(`[Delimit] BLOCKED: ${result.reason}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (result.warnings.length > 0) {
|
|
73
|
+
for (const w of result.warnings) {
|
|
74
|
+
console.error(`[Delimit] Warning: ${w}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
process.exit(0);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Delimit Governance Rules for Cursor
|
|
4
|
+
*
|
|
5
|
+
* Cursor doesn't have a hook system like Claude Code or Codex,
|
|
6
|
+
* so governance enforcement happens server-side via MCP tool calls.
|
|
7
|
+
* This adapter manages the .cursorrules and .cursor/rules/ files
|
|
8
|
+
* that guide Cursor's behavior.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
const HOME = process.env.HOME || '';
|
|
15
|
+
const CURSOR_DIR = path.join(HOME, '.cursor');
|
|
16
|
+
const CURSOR_RULES_DIR = path.join(CURSOR_DIR, 'rules');
|
|
17
|
+
const CURSORRULES_FILE = path.join(HOME, '.cursorrules');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Install Delimit governance rules into Cursor.
|
|
21
|
+
* Creates both .cursorrules (legacy) and .cursor/rules/delimit.md (new).
|
|
22
|
+
*/
|
|
23
|
+
function installRules(version) {
|
|
24
|
+
const rules = getDelimitRules(version);
|
|
25
|
+
|
|
26
|
+
// Install to .cursor/rules/delimit.md (new location, Cursor 0.45+)
|
|
27
|
+
if (fs.existsSync(CURSOR_DIR)) {
|
|
28
|
+
fs.mkdirSync(CURSOR_RULES_DIR, { recursive: true });
|
|
29
|
+
const rulesFile = path.join(CURSOR_RULES_DIR, 'delimit.md');
|
|
30
|
+
fs.writeFileSync(rulesFile, rules);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return { installed: true, paths: [CURSORRULES_FILE, path.join(CURSOR_RULES_DIR, 'delimit.md')] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Remove Delimit rules from Cursor.
|
|
38
|
+
*/
|
|
39
|
+
function uninstallRules() {
|
|
40
|
+
const removed = [];
|
|
41
|
+
|
|
42
|
+
// Remove from .cursor/rules/
|
|
43
|
+
const rulesFile = path.join(CURSOR_RULES_DIR, 'delimit.md');
|
|
44
|
+
if (fs.existsSync(rulesFile)) {
|
|
45
|
+
fs.unlinkSync(rulesFile);
|
|
46
|
+
removed.push(rulesFile);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { removed };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getDelimitRules(version) {
|
|
53
|
+
return `# Delimit Governance (v${version})
|
|
54
|
+
|
|
55
|
+
## On every session start:
|
|
56
|
+
1. Call \`delimit_ledger_context\` to check for open tasks
|
|
57
|
+
2. Call \`delimit_gov_health\` to check governance status
|
|
58
|
+
|
|
59
|
+
## After editing code:
|
|
60
|
+
- After editing UI/CSS: call \`delimit_design_validate_responsive\`
|
|
61
|
+
- After editing API specs: call \`delimit_lint\`
|
|
62
|
+
- After editing tests: call \`delimit_test_smoke\`
|
|
63
|
+
|
|
64
|
+
## Before deploying:
|
|
65
|
+
1. Call \`delimit_security_audit\`
|
|
66
|
+
2. Call \`delimit_test_smoke\`
|
|
67
|
+
3. Call \`delimit_deploy_plan\`
|
|
68
|
+
|
|
69
|
+
## Before committing:
|
|
70
|
+
- Call \`delimit_repo_diagnose\` to check for common issues
|
|
71
|
+
|
|
72
|
+
## Governance enforcement:
|
|
73
|
+
- All tool calls route through governance automatically (server-side)
|
|
74
|
+
- Critical actions are blocked until approved
|
|
75
|
+
- High-risk actions require approval in enforce mode
|
|
76
|
+
- Check mode: advisory (warn only), guarded (block critical), enforce (block critical + high-risk)
|
|
77
|
+
|
|
78
|
+
## Links
|
|
79
|
+
- Docs: https://delimit.ai/docs
|
|
80
|
+
- GitHub: https://github.com/delimit-ai/delimit-mcp-server
|
|
81
|
+
`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { installRules, uninstallRules, getDelimitRules };
|
|
85
|
+
|
|
86
|
+
// CLI entry point
|
|
87
|
+
if (require.main === module) {
|
|
88
|
+
const action = process.argv[2] || 'install';
|
|
89
|
+
const version = process.argv[3] || '3.11.9';
|
|
90
|
+
if (action === 'install') {
|
|
91
|
+
const result = installRules(version);
|
|
92
|
+
console.log(`Installed Delimit rules to Cursor: ${result.paths.join(', ')}`);
|
|
93
|
+
} else if (action === 'uninstall') {
|
|
94
|
+
const result = uninstallRules();
|
|
95
|
+
console.log(`Removed: ${result.removed.join(', ') || 'nothing to remove'}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/bin/delimit-setup.js
CHANGED
|
@@ -54,7 +54,7 @@ async function main() {
|
|
|
54
54
|
log(blue(' / / / / __/ / / / // /|_/ // / / / '));
|
|
55
55
|
log(blue(' / /_/ / /___/ /____/ // / / // / / / '));
|
|
56
56
|
log(blue('/_____/_____/_____/___/_/ /_/___/ /_/ '));
|
|
57
|
-
log(dim('
|
|
57
|
+
log(dim(' Unify all AI coding assistants'));
|
|
58
58
|
log('');
|
|
59
59
|
|
|
60
60
|
// Step 1: Check prerequisites
|
|
@@ -415,13 +415,23 @@ Run full governance compliance checks. Verify security, policy compliance, evide
|
|
|
415
415
|
}
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
-
// Cursor rules
|
|
418
|
+
// Cursor rules (legacy .cursorrules + new .cursor/rules/ directory)
|
|
419
419
|
const cursorRules = path.join(os.homedir(), '.cursorrules');
|
|
420
420
|
if (fs.existsSync(path.join(os.homedir(), '.cursor'))) {
|
|
421
421
|
const cursorResult = upsertDelimitSection(cursorRules);
|
|
422
422
|
if (cursorResult.action !== 'unchanged') {
|
|
423
423
|
log(` ${green('✓')} ${cursorResult.action === 'created' ? 'Created' : 'Updated'} ${cursorRules}`);
|
|
424
424
|
}
|
|
425
|
+
// Also install to .cursor/rules/delimit.md (Cursor 0.45+)
|
|
426
|
+
try {
|
|
427
|
+
const cursorRulesDir = path.join(os.homedir(), '.cursor', 'rules');
|
|
428
|
+
fs.mkdirSync(cursorRulesDir, { recursive: true });
|
|
429
|
+
const cursorAdapter = require('../adapters/cursor-rules');
|
|
430
|
+
cursorAdapter.installRules(pkg.version);
|
|
431
|
+
log(` ${green('✓')} Installed governance rules to .cursor/rules/delimit.md`);
|
|
432
|
+
} catch (e) {
|
|
433
|
+
log(` ${dim(' Could not install .cursor/rules: ' + e.message)}`);
|
|
434
|
+
}
|
|
425
435
|
}
|
|
426
436
|
|
|
427
437
|
// Silent: auto-detect API keys and configure models.json (no output)
|
|
@@ -697,7 +707,7 @@ function getDelimitSection() {
|
|
|
697
707
|
return `<!-- delimit:start v${version} -->
|
|
698
708
|
# Delimit
|
|
699
709
|
|
|
700
|
-
|
|
710
|
+
Unify all AI coding assistants with persistent context, governance, and multi-model debate.
|
|
701
711
|
|
|
702
712
|
## On every session start:
|
|
703
713
|
1. Call \`delimit_ledger_context\` to check for open tasks
|
|
@@ -746,7 +756,7 @@ Add breaking change detection to any repo:
|
|
|
746
756
|
|
|
747
757
|
## Links
|
|
748
758
|
- Docs: https://delimit.ai/docs
|
|
749
|
-
- GitHub: https://github.com/delimit-ai/delimit
|
|
759
|
+
- GitHub: https://github.com/delimit-ai/delimit-mcp-server
|
|
750
760
|
- Action: https://github.com/marketplace/actions/delimit-api-governance
|
|
751
761
|
<!-- delimit:end -->`;
|
|
752
762
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delimit-cli",
|
|
3
3
|
"mcpName": "io.github.delimit-ai/delimit-mcp-server",
|
|
4
|
-
"version": "3.11.
|
|
4
|
+
"version": "3.11.11",
|
|
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": [
|
|
8
8
|
"bin/",
|
|
9
9
|
"lib/",
|
|
10
|
+
"adapters/",
|
|
10
11
|
"gateway/",
|
|
11
12
|
"server.json",
|
|
12
13
|
"README.md",
|
package/server.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
"url": "https://github.com/delimit-ai/delimit-mcp-server",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "3.11.
|
|
10
|
+
"version": "3.11.10",
|
|
11
11
|
"websiteUrl": "https://delimit.ai",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "delimit-cli",
|
|
16
|
-
"version": "3.11.
|
|
16
|
+
"version": "3.11.10",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
}
|