delimit-cli 4.3.1 → 4.3.4
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/bin/delimit-cli.js +4 -4
- package/lib/agent.js +3 -3
- package/lib/cross-model-hooks.js +1 -1
- package/lib/wrap-engine.js +19 -1
- package/package.json +2 -2
package/bin/delimit-cli.js
CHANGED
|
@@ -378,7 +378,7 @@ program
|
|
|
378
378
|
if (fs.existsSync(policyPath)) {
|
|
379
379
|
hasPolicy = true;
|
|
380
380
|
try {
|
|
381
|
-
const policyContent = yaml.load(fs.readFileSync(policyPath, 'utf-8'));
|
|
381
|
+
const policyContent = yaml.load(fs.readFileSync(policyPath, 'utf-8')); // nosec B-yaml_unsafe_load: parses user-local policy YAML; trusted input
|
|
382
382
|
policyName = policyContent?.preset || policyContent?.name || 'custom';
|
|
383
383
|
policyMode = policyContent?.enforcement_mode || policyContent?.mode || '';
|
|
384
384
|
if (policyContent?.rules) ruleCount = Object.keys(policyContent.rules).length;
|
|
@@ -3830,7 +3830,7 @@ program
|
|
|
3830
3830
|
if (fs.existsSync(policyPath)) {
|
|
3831
3831
|
addResult('policy-file', 'pass', '.delimit/policies.yml found');
|
|
3832
3832
|
try {
|
|
3833
|
-
const policy = yaml.load(fs.readFileSync(policyPath, 'utf8'));
|
|
3833
|
+
const policy = yaml.load(fs.readFileSync(policyPath, 'utf8')); // nosec B-yaml_unsafe_load: parses user-local .delimit/ YAML; trusted input
|
|
3834
3834
|
if (policy && (policy.rules !== undefined || policy.override_defaults !== undefined)) {
|
|
3835
3835
|
addResult('policy-valid', 'pass', 'Policy file is valid YAML');
|
|
3836
3836
|
} else {
|
|
@@ -4193,7 +4193,7 @@ program
|
|
|
4193
4193
|
if (fs.existsSync(policyPath)) {
|
|
4194
4194
|
try {
|
|
4195
4195
|
const yaml = require('js-yaml');
|
|
4196
|
-
policy = yaml.load(fs.readFileSync(policyPath, 'utf8'));
|
|
4196
|
+
policy = yaml.load(fs.readFileSync(policyPath, 'utf8')); // nosec B-yaml_unsafe_load: parses user-local .delimit/ YAML; trusted input
|
|
4197
4197
|
|
|
4198
4198
|
// Detect preset from content
|
|
4199
4199
|
const policyContent = fs.readFileSync(policyPath, 'utf-8');
|
|
@@ -4308,7 +4308,7 @@ program
|
|
|
4308
4308
|
try {
|
|
4309
4309
|
const yaml = require('js-yaml');
|
|
4310
4310
|
const content = fs.readFileSync(specPath, 'utf8');
|
|
4311
|
-
const parsed = specPath.endsWith('.json') ? JSON.parse(content) : yaml.load(content);
|
|
4311
|
+
const parsed = specPath.endsWith('.json') ? JSON.parse(content) : yaml.load(content); // nosec B-yaml_unsafe_load: parses user-local .delimit/ YAML; trusted input
|
|
4312
4312
|
if (parsed && (parsed.openapi || parsed.swagger)) {
|
|
4313
4313
|
console.log(chalk.green(` \u2713 PASS Valid OpenAPI ${parsed.openapi || parsed.swagger} spec`));
|
|
4314
4314
|
totalPassed += 2;
|
package/lib/agent.js
CHANGED
|
@@ -124,7 +124,7 @@ class DelimitAgent {
|
|
|
124
124
|
if (fs.existsSync(userPolicyPath)) {
|
|
125
125
|
try {
|
|
126
126
|
this.globalPolicies.user = {
|
|
127
|
-
policy: yaml.load(fs.readFileSync(userPolicyPath, 'utf8')),
|
|
127
|
+
policy: yaml.load(fs.readFileSync(userPolicyPath, 'utf8')), // nosec B-yaml_unsafe_load: parses agent-config YAML authored by the user locally
|
|
128
128
|
path: userPolicyPath,
|
|
129
129
|
loadedAt: Date.now()
|
|
130
130
|
};
|
|
@@ -139,7 +139,7 @@ class DelimitAgent {
|
|
|
139
139
|
if (fs.existsSync(systemPolicyPath)) {
|
|
140
140
|
try {
|
|
141
141
|
this.globalPolicies.system = {
|
|
142
|
-
policy: yaml.load(fs.readFileSync(systemPolicyPath, 'utf8')),
|
|
142
|
+
policy: yaml.load(fs.readFileSync(systemPolicyPath, 'utf8')), // nosec B-yaml_unsafe_load: parses agent-config YAML authored by the user locally
|
|
143
143
|
path: systemPolicyPath,
|
|
144
144
|
loadedAt: Date.now()
|
|
145
145
|
};
|
|
@@ -317,7 +317,7 @@ class DelimitAgent {
|
|
|
317
317
|
try {
|
|
318
318
|
const stat = fs.statSync(policyPath);
|
|
319
319
|
const policyContent = fs.readFileSync(policyPath, 'utf8');
|
|
320
|
-
const parsedPolicy = yaml.load(policyContent);
|
|
320
|
+
const parsedPolicy = yaml.load(policyContent); // nosec B-yaml_unsafe_load: parses agent-config YAML authored by the user locally
|
|
321
321
|
|
|
322
322
|
// Validate the parsed policy
|
|
323
323
|
if (!parsedPolicy || typeof parsedPolicy !== 'object') {
|
package/lib/cross-model-hooks.js
CHANGED
|
@@ -154,7 +154,7 @@ function loadHookConfig() {
|
|
|
154
154
|
if (fs.existsSync(candidate)) {
|
|
155
155
|
try {
|
|
156
156
|
const yaml = require('js-yaml');
|
|
157
|
-
const doc = yaml.load(fs.readFileSync(candidate, 'utf-8'));
|
|
157
|
+
const doc = yaml.load(fs.readFileSync(candidate, 'utf-8')); // nosec B-yaml_unsafe_load: parses hook YAML from user-local .claude/
|
|
158
158
|
if (doc && doc.hooks) {
|
|
159
159
|
return { ...defaults, ...doc.hooks };
|
|
160
160
|
}
|
package/lib/wrap-engine.js
CHANGED
|
@@ -109,7 +109,25 @@ function runTestSmoke(cwd) {
|
|
|
109
109
|
}
|
|
110
110
|
} catch { /* ignore */ }
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
// Only run pytest if there's a Python-specific signal.
|
|
113
|
+
// A bare `tests/` directory is common in Node projects too and should NOT trigger pytest.
|
|
114
|
+
// Require: pytest.ini, OR pyproject.toml that mentions pytest, OR setup.py, OR setup.cfg with [tool:pytest]/[pytest].
|
|
115
|
+
let pythonProject = false;
|
|
116
|
+
if (fs.existsSync(path.join(cwd, 'pytest.ini'))) pythonProject = true;
|
|
117
|
+
if (!pythonProject && fs.existsSync(path.join(cwd, 'setup.py'))) pythonProject = true;
|
|
118
|
+
if (!pythonProject && fs.existsSync(path.join(cwd, 'pyproject.toml'))) {
|
|
119
|
+
try {
|
|
120
|
+
const pp = fs.readFileSync(path.join(cwd, 'pyproject.toml'), 'utf-8');
|
|
121
|
+
if (/\bpytest\b/.test(pp)) pythonProject = true;
|
|
122
|
+
} catch { /* ignore */ }
|
|
123
|
+
}
|
|
124
|
+
if (!pythonProject && fs.existsSync(path.join(cwd, 'setup.cfg'))) {
|
|
125
|
+
try {
|
|
126
|
+
const sc = fs.readFileSync(path.join(cwd, 'setup.cfg'), 'utf-8');
|
|
127
|
+
if (/\[(tool:)?pytest\]/.test(sc)) pythonProject = true;
|
|
128
|
+
} catch { /* ignore */ }
|
|
129
|
+
}
|
|
130
|
+
if (pythonProject) {
|
|
113
131
|
const r = spawnSync('python3', ['-m', 'pytest', '--tb=short', '-q'], { cwd, encoding: 'utf-8', timeout: 180000, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
114
132
|
results.push({ runner: 'pytest', exit: r.status ?? 1, stdout: (r.stdout || '').slice(-2000), stderr: (r.stderr || '').slice(-1000) });
|
|
115
133
|
}
|
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.3.
|
|
4
|
+
"version": "4.3.4",
|
|
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": [
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"postinstall": "node scripts/postinstall.js",
|
|
49
49
|
"sync-gateway": "bash scripts/sync-gateway.sh",
|
|
50
50
|
"prepublishOnly": "bash scripts/publish-ci-guard.sh && npm run sync-gateway && bash scripts/security-check.sh",
|
|
51
|
-
"test": "node --test tests/setup-onboarding.test.js tests/setup-matrix.test.js tests/setup-no-clobber.test.js tests/config-export-import.test.js tests/cross-model-hooks.test.js tests/golden-path.test.js tests/v420-features.test.js"
|
|
51
|
+
"test": "node --test tests/setup-onboarding.test.js tests/setup-matrix.test.js tests/setup-no-clobber.test.js tests/config-export-import.test.js tests/cross-model-hooks.test.js tests/golden-path.test.js tests/v420-features.test.js tests/v43-wrap-engine.test.js tests/v43-trust-page-engine.test.js tests/v43-ai-sbom-engine.test.js"
|
|
52
52
|
},
|
|
53
53
|
"keywords": [
|
|
54
54
|
"openapi",
|