codekin 0.3.1 → 0.3.3

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/README.md CHANGED
@@ -14,7 +14,7 @@ Web UI for Claude Code sessions — multi-session support, WebSocket streaming,
14
14
  **One-liner:**
15
15
 
16
16
  ```bash
17
- curl -fsSL https://raw.githubusercontent.com/Multiplier-Labs/codekin/main/install.sh | bash
17
+ curl -fsSL codekin.ai/install.sh | bash
18
18
  ```
19
19
 
20
20
  This will:
@@ -51,7 +51,7 @@ codekin setup --regenerate # Generate a new auth token
51
51
  Re-run the install script — it's idempotent and will upgrade to the latest version:
52
52
 
53
53
  ```bash
54
- curl -fsSL https://raw.githubusercontent.com/Multiplier-Labs/codekin/main/install.sh | bash
54
+ curl -fsSL codekin.ai/install.sh | bash
55
55
  ```
56
56
 
57
57
  Or upgrade manually:
package/bin/codekin.mjs CHANGED
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  import { execSync, execFileSync, spawnSync } from 'child_process'
15
- import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'fs'
15
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync, createReadStream } from 'fs'
16
16
  import { homedir, platform } from 'os'
17
17
  import { join, dirname } from 'path'
18
18
  import { fileURLToPath } from 'url'
@@ -62,13 +62,29 @@ function getPort() {
62
62
  return parseInt(env.PORT || String(DEFAULT_PORT), 10)
63
63
  }
64
64
 
65
+ function openTtyInput() {
66
+ // When piped (curl | bash), stdin is not a TTY — open /dev/tty directly
67
+ if (process.stdin.isTTY) return { input: process.stdin, cleanup: null }
68
+ try {
69
+ const tty = createReadStream('/dev/tty', { encoding: 'utf-8' })
70
+ return { input: tty, cleanup: () => tty.destroy() }
71
+ } catch {
72
+ // No TTY available (CI, headless) — fall back to stdin
73
+ return { input: process.stdin, cleanup: null }
74
+ }
75
+ }
76
+
65
77
  function prompt(question) {
66
- const rl = createInterface({ input: process.stdin, output: process.stdout })
78
+ const { input, cleanup } = openTtyInput()
79
+ const rl = createInterface({ input, output: process.stdout })
67
80
  return new Promise(resolve => {
68
81
  rl.question(question, answer => {
69
82
  rl.close()
83
+ if (cleanup) cleanup()
70
84
  resolve(answer.trim())
71
85
  })
86
+ // If input closes without an answer (non-interactive), resolve empty
87
+ rl.on('close', () => resolve(''))
72
88
  })
73
89
  }
74
90
 
@@ -113,7 +129,7 @@ async function cmdSetup({ regenerate = false } = {}) {
113
129
  if (existingToken && !regenerate) {
114
130
  console.log('Auth token: (already exists, use --regenerate to replace)')
115
131
  } else {
116
- const token = randomBytes(32).toString('hex')
132
+ const token = randomBytes(16).toString('base64url')
117
133
  writeFileSync(TOKEN_FILE, token + '\n', { mode: 0o600 })
118
134
  console.log('Auth token: generated')
119
135
  }