delimit-cli 4.1.9 → 4.1.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.
@@ -321,28 +321,73 @@ function installClaudeHooks(tool, hookConfig) {
321
321
  }
322
322
  const changes = [];
323
323
 
324
- // --- SessionStart hook (no condition) ---
325
- // Always update to latest version (reinstall-safe)
324
+ // --- SessionStart hook ---
325
+ // Write a standalone bash script so it works without npm in PATH
326
326
  if (hookConfig.session_start) {
327
+ const hooksDir = path.join(home, '.claude', 'hooks');
328
+ fs.mkdirSync(hooksDir, { recursive: true });
329
+ const hookScript = path.join(hooksDir, 'delimit');
330
+ const delimitHome = path.join(home, '.delimit');
331
+ fs.writeFileSync(hookScript, `#!/bin/bash
332
+ # Delimit SessionStart — generated by delimit-cli setup
333
+ DELIMIT_HOME="\${DELIMIT_HOME:-${delimitHome}}"
334
+ echo "=== Delimit Status ==="
335
+ # Governance
336
+ if [ -f "./delimit.yml" ] || [ -f "./.delimit/policies.yml" ]; then
337
+ echo "Governance: active | policy=project"
338
+ elif [ -f "$DELIMIT_HOME/delimit.yml" ]; then
339
+ echo "Governance: active | policy=user"
340
+ else
341
+ echo "Governance: not initialized -- run npx delimit-cli init"
342
+ fi
343
+ # Server + tools
344
+ SERVER="$DELIMIT_HOME/server/ai/server.py"
345
+ if [ -f "$SERVER" ]; then
346
+ TOOLS=$(grep -c '@mcp.tool' "$SERVER" 2>/dev/null || echo "0")
347
+ echo "Server: ready ($TOOLS tools)"
348
+ else
349
+ echo "Server: not installed -- run npx delimit-cli setup"
350
+ fi
351
+ # Hooks + audit
352
+ [ -f "${home}/.claude/settings.json" ] && grep -q '"hooks"' "${home}/.claude/settings.json" 2>/dev/null && HOOKS="enabled" || HOOKS="disabled"
353
+ [ -d "$DELIMIT_HOME/audit" ] && AUDIT="on" || AUDIT="off"
354
+ echo "Hooks: $HOOKS | Audit: $AUDIT"
355
+ # MCP
356
+ [ -f "${home}/.mcp.json" ] && grep -q "delimit" "${home}/.mcp.json" 2>/dev/null && echo "MCP: delimit registered" || echo "MCP: not registered"
357
+ # Models
358
+ MODELS=""
359
+ [ -n "$XAI_API_KEY" ] && MODELS="\${MODELS}Grok + "
360
+ [ -n "$GOOGLE_APPLICATION_CREDENTIALS" ] && MODELS="\${MODELS}Gemini + "
361
+ [ -n "$OPENAI_API_KEY" ] && MODELS="\${MODELS}Codex + "
362
+ [ -f "$DELIMIT_HOME/models.json" ] && MODELS=$(python3 -c "import json; d=json.load(open('$DELIMIT_HOME/models.json')); print(' + '.join(v.get('name',k) for k,v in d.items() if v.get('enabled')))" 2>/dev/null) || true
363
+ [ -n "$MODELS" ] && echo "Deliberation: \${MODELS% + }"
364
+ # Last session
365
+ SESSIONS="$DELIMIT_HOME/sessions"
366
+ if [ -d "$SESSIONS" ]; then
367
+ LATEST=$(ls -t "$SESSIONS"/session_*.json 2>/dev/null | head -1)
368
+ [ -n "$LATEST" ] && python3 -c "import json; d=json.load(open('$LATEST')); s=d.get('summary','')[:150]; print(f'Last session: {s}')" 2>/dev/null
369
+ fi
370
+ echo "=== Delimit Ready ==="
371
+ `);
372
+ fs.chmodSync(hookScript, '755');
373
+
327
374
  if (!config.hooks.SessionStart) {
328
375
  config.hooks.SessionStart = [];
329
376
  }
330
- const existing = findClaudeHookGroup(config.hooks.SessionStart, 'delimit-cli hook session-start');
331
- if (existing) {
332
- // Remove old entry so we can replace it
333
- const idx = config.hooks.SessionStart.indexOf(existing);
334
- if (idx >= 0) config.hooks.SessionStart.splice(idx, 1);
335
- }
336
- {
337
- config.hooks.SessionStart.push({
338
- matcher: '',
339
- hooks: [{
340
- type: 'command',
341
- command: `${npxCmd} hook session-start`,
342
- }],
343
- });
344
- changes.push('SessionStart');
345
- }
377
+ // Remove any old delimit hooks (both script and npm command variants)
378
+ config.hooks.SessionStart = config.hooks.SessionStart.filter(group => {
379
+ const cmds = (group.hooks || []).map(h => h.command || '');
380
+ return !cmds.some(c => c.includes('delimit'));
381
+ });
382
+ config.hooks.SessionStart.push({
383
+ matcher: '',
384
+ hooks: [{
385
+ type: 'command',
386
+ command: hookScript,
387
+ timeout: 10,
388
+ }],
389
+ });
390
+ changes.push('SessionStart');
346
391
  }
347
392
 
348
393
  // --- PreToolUse: pre-tool hook scoped to Edit/Write on spec files ---
@@ -802,9 +847,23 @@ async function hookSessionStart() {
802
847
  const lines = [];
803
848
  lines.push('=== Delimit Status ===');
804
849
 
805
- // Server status + tool count
806
850
  const home = getHome();
807
- const serverFile = path.join(home, '.delimit', 'server', 'ai', 'server.py');
851
+ const delimitHome = path.join(home, '.delimit');
852
+ const cwd = process.cwd();
853
+
854
+ // Governance status + policy source
855
+ const projectPolicy = fs.existsSync(path.join(cwd, 'delimit.yml')) || fs.existsSync(path.join(cwd, '.delimit', 'policies.yml'));
856
+ const userPolicy = fs.existsSync(path.join(delimitHome, 'delimit.yml'));
857
+ if (projectPolicy) {
858
+ lines.push('Governance: active | policy=project');
859
+ } else if (userPolicy) {
860
+ lines.push('Governance: active | policy=user');
861
+ } else {
862
+ lines.push('Governance: not initialized -- run npx delimit-cli init');
863
+ }
864
+
865
+ // Server status + tool count
866
+ const serverFile = path.join(delimitHome, 'server', 'ai', 'server.py');
808
867
  if (fs.existsSync(serverFile)) {
809
868
  try {
810
869
  const content = fs.readFileSync(serverFile, 'utf-8');
@@ -817,20 +876,43 @@ async function hookSessionStart() {
817
876
  lines.push('Server: not installed -- run npx delimit-cli setup');
818
877
  }
819
878
 
820
- // Governance status
821
- const cwd = process.cwd();
822
- const hasPolicy = fs.existsSync(path.join(cwd, 'delimit.yml'))
823
- || fs.existsSync(path.join(cwd, '.delimit.yml'))
824
- || fs.existsSync(path.join(cwd, '.delimit', 'policies.yml'));
879
+ // Hooks + audit
880
+ const settingsFile = path.join(home, '.claude', 'settings.json');
881
+ const hooksEnabled = fs.existsSync(settingsFile) && fs.readFileSync(settingsFile, 'utf-8').includes('"hooks"');
882
+ const auditOn = fs.existsSync(path.join(delimitHome, 'audit'));
883
+ lines.push(`Hooks: ${hooksEnabled ? 'enabled' : 'disabled'} | Audit: ${auditOn ? 'on' : 'off'}`);
825
884
 
826
- if (hasPolicy) {
827
- lines.push('Governance: active');
885
+ // MCP registration
886
+ const mcpFile = path.join(home, '.mcp.json');
887
+ const mcpRegistered = fs.existsSync(mcpFile) && fs.readFileSync(mcpFile, 'utf-8').includes('delimit');
888
+ lines.push(`MCP: ${mcpRegistered ? 'delimit registered' : 'not registered -- run npx delimit-cli setup'}`);
889
+
890
+ // Deliberation models
891
+ const modelsFile = path.join(delimitHome, 'models.json');
892
+ const modelNames = [];
893
+ try {
894
+ if (fs.existsSync(modelsFile)) {
895
+ const models = JSON.parse(fs.readFileSync(modelsFile, 'utf-8'));
896
+ for (const [key, val] of Object.entries(models)) {
897
+ if (val && val.enabled) modelNames.push(val.name || key);
898
+ }
899
+ }
900
+ } catch {}
901
+ // Also check env vars for available models
902
+ if (modelNames.length === 0) {
903
+ const envModels = [];
904
+ if (process.env.XAI_API_KEY) envModels.push('Grok');
905
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) envModels.push('Gemini');
906
+ if (process.env.OPENAI_API_KEY) envModels.push('Codex');
907
+ if (envModels.length > 0) {
908
+ lines.push(`Deliberation: ${envModels.join(' + ')}`);
909
+ }
828
910
  } else {
829
- lines.push('Governance: not initialized -- run npx delimit-cli init');
911
+ lines.push(`Deliberation: ${modelNames.join(' + ')}`);
830
912
  }
831
913
 
832
914
  // Last session context (prevents cross-session drift)
833
- const sessionsDir = path.join(home, '.delimit', 'sessions');
915
+ const sessionsDir = path.join(delimitHome, 'sessions');
834
916
  try {
835
917
  if (fs.existsSync(sessionsDir)) {
836
918
  const sessions = fs.readdirSync(sessionsDir).filter(f => f.startsWith('session_')).sort().reverse();
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.9",
4
+ "version": "4.1.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": [