delimit-cli 4.1.19 → 4.1.20

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.
@@ -874,11 +874,20 @@ program
874
874
  } catch (e) {}
875
875
  }
876
876
 
877
- // 7. Shims
877
+ // 7. Shims + wrapped binaries
878
878
  const shimsDir = path.join(HOME, '.delimit', 'shims');
879
879
  if (fs.existsSync(shimsDir)) {
880
880
  changes.push({ target: '~/.delimit/shims/', action: 'Remove CLI shims directory' });
881
881
  }
882
+ for (const tool of ['claude', 'codex', 'gemini']) {
883
+ const searchPaths = [`/usr/local/bin/${tool}-real`, `/usr/bin/${tool}-real`, path.join(HOME, '.local', 'bin', `${tool}-real`)];
884
+ for (const p of searchPaths) {
885
+ if (fs.existsSync(p)) {
886
+ changes.push({ target: p.replace(HOME, '~'), action: `Restore original ${tool} binary` });
887
+ break;
888
+ }
889
+ }
890
+ }
882
891
 
883
892
  // 8. Cross-model governance hooks (LED-202)
884
893
  const claudeSettingsPath = path.join(HOME, '.claude', 'settings.json');
@@ -992,6 +1001,29 @@ program
992
1001
  } catch (e) {}
993
1002
  }
994
1003
 
1004
+ // Restore wrapped binaries before removing shims
1005
+ for (const tool of ['claude', 'codex', 'gemini']) {
1006
+ const searchPaths = [
1007
+ `/usr/local/bin/${tool}`,
1008
+ `/usr/bin/${tool}`,
1009
+ path.join(HOME, '.local', 'bin', tool),
1010
+ ];
1011
+ try {
1012
+ const npmBin = execSync('npm bin -g 2>/dev/null', { encoding: 'utf-8', timeout: 3000 }).trim();
1013
+ if (npmBin) searchPaths.push(path.join(npmBin, tool));
1014
+ } catch {}
1015
+ for (const p of searchPaths) {
1016
+ const realPath = p + '-real';
1017
+ try {
1018
+ if (fs.existsSync(realPath)) {
1019
+ fs.renameSync(realPath, p);
1020
+ console.log(chalk.green(`✓ Restored original ${tool} binary`));
1021
+ break;
1022
+ }
1023
+ } catch {}
1024
+ }
1025
+ }
1026
+
995
1027
  // Remove shims
996
1028
  if (fs.existsSync(shimsDir)) {
997
1029
  try {
@@ -743,12 +743,16 @@ printf " \${MAGENTA}\${BOLD}[Delimit]\${RESET} \${MAGENTA}═══════
743
743
  sleep 0.08
744
744
  printf " \${GREEN}\${BOLD}[Delimit]\${RESET} \${GREEN}✓ Allowed\${RESET}\\n"
745
745
  echo ""
746
- # Find real binary — check common paths then fallback to PATH search (excluding shim dir)
746
+ # Find real binary — check renamed binary first, then common paths
747
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
748
+ # 1. Check for renamed binary (tool-real) next to this shim
749
+ [ -x "$SCRIPT_DIR/${toolName}-real" ] && exec "$SCRIPT_DIR/${toolName}-real" "$@"
750
+ # 2. Check common paths (skip self)
747
751
  SELF="$(readlink -f "$0" 2>/dev/null || echo "$0")"
748
- for c in /usr/bin/${toolName} /usr/local/bin/${toolName} "$HOME/.local/bin/${toolName}" "$(npm bin -g 2>/dev/null)/${toolName}"; do
752
+ for c in /usr/local/bin/${toolName}-real /usr/bin/${toolName}-real "$HOME/.local/bin/${toolName}-real" /usr/bin/${toolName} /usr/local/bin/${toolName} "$HOME/.local/bin/${toolName}" "$(npm bin -g 2>/dev/null)/${toolName}"; do
749
753
  [ -x "$c" ] && [ "$(readlink -f "$c" 2>/dev/null)" != "$SELF" ] && exec "$c" "$@"
750
754
  done
751
- # Last resort: search PATH excluding shim directory
755
+ # 3. Last resort: search PATH excluding shim directory
752
756
  REAL=$(PATH=$(echo "$PATH" | tr ':' '\\n' | grep -v '.delimit/shims' | tr '\\n' ':') command -v ${toolName} 2>/dev/null)
753
757
  [ -x "$REAL" ] && exec "$REAL" "$@"
754
758
  echo "[Delimit] ${toolName} not found in PATH" >&2
@@ -767,6 +771,60 @@ exit 127
767
771
  fs.chmodSync(shimPath, '755');
768
772
  }
769
773
 
774
+ // Rename+wrap: place shim at the real binary's location
775
+ // so it works immediately without PATH changes
776
+ for (const tool of ['claude', 'codex', 'gemini']) {
777
+ try {
778
+ // Find real binary location
779
+ let realPath = null;
780
+ const searchPaths = [
781
+ `/usr/local/bin/${tool}`,
782
+ `/usr/bin/${tool}`,
783
+ path.join(os.homedir(), '.local', 'bin', tool),
784
+ ];
785
+ // Also check npm global bin
786
+ try {
787
+ const npmBin = execSync('npm bin -g 2>/dev/null', { encoding: 'utf-8', timeout: 3000 }).trim();
788
+ if (npmBin) searchPaths.push(path.join(npmBin, tool));
789
+ } catch {}
790
+
791
+ for (const p of searchPaths) {
792
+ try {
793
+ if (fs.existsSync(p) && fs.statSync(p).isFile()) {
794
+ // Check it's the real binary, not already our shim
795
+ const content = fs.readFileSync(p, 'utf-8').substring(0, 200);
796
+ if (!content.includes('Delimit Governance Shim')) {
797
+ realPath = p;
798
+ break;
799
+ }
800
+ }
801
+ } catch {}
802
+ }
803
+
804
+ if (realPath) {
805
+ const dir = path.dirname(realPath);
806
+ const realDest = path.join(dir, `${tool}-real`);
807
+ // Only rename if not already renamed
808
+ if (!fs.existsSync(realDest)) {
809
+ fs.renameSync(realPath, realDest);
810
+ }
811
+ // Place our shim at the original location
812
+ const shimContent = fs.readFileSync(path.join(shimsDir, tool), 'utf-8');
813
+ // Update shim to also check for tool-real in same directory
814
+ const patchedShim = shimContent.replace(
815
+ `echo "[Delimit] ${tool} not found in PATH"`,
816
+ `# Check for renamed binary next to shim\n` +
817
+ `SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"\n` +
818
+ `[ -x "$SCRIPT_DIR/${tool}-real" ] && exec "$SCRIPT_DIR/${tool}-real" "$@"\n` +
819
+ `echo "[Delimit] ${tool} not found in PATH"`
820
+ );
821
+ fs.writeFileSync(realPath, patchedShim);
822
+ fs.chmodSync(realPath, '755');
823
+ log(` ${green('✓')} ${tool}: wrapped at ${dim(realPath)}`);
824
+ }
825
+ } catch {}
826
+ }
827
+
770
828
  // Add to PATH in shell rc files (create if missing)
771
829
  const pathLine = `export PATH="${shimsDir}:$PATH" # Delimit governance wrapping`;
772
830
  let pathWritten = false;
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.19",
4
+ "version": "4.1.20",
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": [