@ekkos/cli 1.0.32 → 1.0.34

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.
@@ -54,10 +54,6 @@ const transcript_repair_1 = require("../capture/transcript-repair");
54
54
  let pty = null;
55
55
  let ptyLoadPromise = null;
56
56
  async function loadPty() {
57
- // node-pty uses native addons that don't load cleanly on Windows.
58
- // All PTY code paths already guard with `!isWindows`, so skip the import entirely.
59
- if (isWindows)
60
- return null;
61
57
  if (pty)
62
58
  return pty;
63
59
  if (!ptyLoadPromise) {
@@ -311,6 +307,7 @@ const isWindows = os.platform() === 'win32';
311
307
  // Core ekkOS patches (eviction, context management) work with all recent versions
312
308
  // Cosmetic patches may fail on newer versions but don't affect functionality
313
309
  const PINNED_CLAUDE_VERSION = 'latest';
310
+ const MIN_CLAUDE_VERSION_FOR_LATEST = process.env.EKKOS_MIN_CLAUDE_VERSION || '2.1.49';
314
311
  // Max output tokens for Claude responses
315
312
  // Default: 16384 (safe for Sonnet 4.5)
316
313
  // Opus 4.5 supports up to 64k - set EKKOS_MAX_OUTPUT_TOKENS=32768 or =65536 to use higher limits
@@ -388,8 +385,8 @@ function getEkkosEnv() {
388
385
  // Format: https://mcp.ekkos.dev/proxy/{userId}/{sessionName}?project={base64(cwd)}
389
386
  // Gateway extracts from URL: /proxy/{userId}/{sessionName}/v1/messages
390
387
  // Project path is base64-encoded to handle special chars safely
391
- const projectPath = process.cwd();
392
- const projectPathEncoded = Buffer.from(projectPath).toString('base64url');
388
+ const projectPath = process.cwd().replace(/\\/g, '/');
389
+ const projectPathEncoded = encodeURIComponent(Buffer.from(projectPath, 'utf-8').toString('base64'));
393
390
  const proxyUrl = `${EKKOS_PROXY_URL}/proxy/${encodeURIComponent(userId)}/${encodeURIComponent(cliSessionName)}?project=${projectPathEncoded}`;
394
391
  env.ANTHROPIC_BASE_URL = proxyUrl;
395
392
  // Proxy URL contains userId + project path — don't leak to terminal
@@ -465,6 +462,24 @@ function getClaudeVersion(claudePath) {
465
462
  return null;
466
463
  }
467
464
  }
465
+ function compareSemver(a, b) {
466
+ const parse = (v) => {
467
+ const m = v.match(/(\d+)\.(\d+)\.(\d+)/);
468
+ if (!m)
469
+ return [0, 0, 0];
470
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
471
+ };
472
+ const pa = parse(a);
473
+ const pb = parse(b);
474
+ for (let i = 0; i < 3; i++) {
475
+ if (pa[i] !== pb[i])
476
+ return pa[i] - pb[i];
477
+ }
478
+ return 0;
479
+ }
480
+ function isVersionAtLeast(version, minVersion) {
481
+ return compareSemver(version, minVersion) >= 0;
482
+ }
468
483
  /**
469
484
  * Check if a Claude installation matches our required version
470
485
  * When PINNED_CLAUDE_VERSION is 'latest', any version is acceptable
@@ -474,8 +489,9 @@ function checkClaudeVersion(claudePath) {
474
489
  if (!version)
475
490
  return false;
476
491
  // 'latest' means any version is acceptable
477
- if (PINNED_CLAUDE_VERSION === 'latest')
478
- return true;
492
+ if (PINNED_CLAUDE_VERSION === 'latest') {
493
+ return isVersionAtLeast(version, MIN_CLAUDE_VERSION_FOR_LATEST);
494
+ }
479
495
  return version === PINNED_CLAUDE_VERSION;
480
496
  }
481
497
  /**
@@ -559,7 +575,12 @@ function resolveClaudePath() {
559
575
  // These binaries do not print the npm-to-native migration warning.
560
576
  const nativeBin = resolveNativeClaudeBin();
561
577
  if (nativeBin) {
562
- return nativeBin;
578
+ const nativeVersion = getClaudeVersion(nativeBin);
579
+ if (PINNED_CLAUDE_VERSION !== 'latest' ||
580
+ (nativeVersion && isVersionAtLeast(nativeVersion, MIN_CLAUDE_VERSION_FOR_LATEST))) {
581
+ return nativeBin;
582
+ }
583
+ console.log(chalk_1.default.yellow(` Native Claude ${nativeVersion || 'unknown'} is below minimum ${MIN_CLAUDE_VERSION_FOR_LATEST}; using managed latest.`));
563
584
  }
564
585
  // PRIORITY 2: ekkOS-managed npm installation (existing users before native installer)
565
586
  if (fs.existsSync(EKKOS_CLAUDE_BIN) && checkClaudeVersion(EKKOS_CLAUDE_BIN)) {
@@ -1024,7 +1045,7 @@ async function run(options) {
1024
1045
  // Handler reference for early spawn (allows replacing buffer handler with real handler)
1025
1046
  let earlyDataHandler = null;
1026
1047
  // Start spawning Claude NOW (before animation) if PTY available
1027
- if (usePty && pty && !isWindows) {
1048
+ if (usePty && pty) {
1028
1049
  try {
1029
1050
  earlySpawnedShell = pty.spawn(claudePath, earlyArgs, {
1030
1051
  name: 'xterm-256color',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekkos/cli",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "description": "Setup ekkOS memory for AI coding assistants (Claude Code, Cursor, Windsurf)",
5
5
  "main": "dist/index.js",
6
6
  "bin": {