delimit-cli 4.3.3 → 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.
@@ -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') {
@@ -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
  }
@@ -109,7 +109,25 @@ function runTestSmoke(cwd) {
109
109
  }
110
110
  } catch { /* ignore */ }
111
111
  }
112
- if (fs.existsSync(path.join(cwd, 'tests')) || fs.existsSync(path.join(cwd, 'pytest.ini')) || fs.existsSync(path.join(cwd, 'pyproject.toml'))) {
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.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": [