gekto 0.0.2 → 0.0.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.
@@ -1,4 +1,5 @@
1
1
  import * as pty from 'node-pty';
2
+ import { CLAUDE_PATH } from '../claudePath.js';
2
3
  export class ClaudeAgent {
3
4
  pty;
4
5
  buffer = '';
@@ -11,9 +12,8 @@ export class ClaudeAgent {
11
12
  this.readyPromise = new Promise((resolve) => {
12
13
  this.resolveReady = resolve;
13
14
  });
14
- // Use shell to resolve claude from PATH (needed for Homebrew on macOS)
15
- const shell = process.env.SHELL || '/bin/bash';
16
- this.pty = pty.spawn(shell, ['-i', '-c', 'claude'], {
15
+ // Use full path to claude binary (resolved at startup)
16
+ this.pty = pty.spawn(CLAUDE_PATH, [], {
17
17
  name: 'xterm-256color',
18
18
  cols: 120,
19
19
  rows: 40,
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'child_process';
2
+ import { CLAUDE_PATH } from '../claudePath.js';
2
3
  export class HeadlessAgent {
3
4
  sessionId = null;
4
5
  config;
@@ -38,11 +39,10 @@ export class HeadlessAgent {
38
39
  }
39
40
  runClaudeStreaming(args, callbacks) {
40
41
  return new Promise((resolve, reject) => {
41
- const proc = spawn('claude', args, {
42
+ const proc = spawn(CLAUDE_PATH, args, {
42
43
  cwd: this.config.workingDir || process.cwd(),
43
44
  env: process.env,
44
45
  stdio: ['pipe', 'pipe', 'pipe'],
45
- shell: true,
46
46
  });
47
47
  this.currentProc = proc;
48
48
  // Close stdin immediately - we pass everything via args
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'child_process';
2
+ import { CLAUDE_PATH } from '../claudePath.js';
2
3
  // === Gekto System Prompt ===
3
4
  const GEKTO_SYSTEM_PROMPT = `You are Gekto, a friendly task orchestration assistant. You help users with coding tasks by delegating work to specialized agents.
4
5
 
@@ -123,11 +124,10 @@ function runClaudeOnce(prompt, systemPrompt, workingDir) {
123
124
  '--dangerously-skip-permissions',
124
125
  ];
125
126
  console.log('[Orchestrator] Running claude (haiku) for orchestration');
126
- const proc = spawn('claude', args, {
127
+ const proc = spawn(CLAUDE_PATH, args, {
127
128
  cwd: workingDir,
128
129
  env: process.env,
129
130
  stdio: ['pipe', 'pipe', 'pipe'],
130
- shell: true,
131
131
  });
132
132
  proc.stdin?.end();
133
133
  let buffer = '';
@@ -1,5 +1,6 @@
1
1
  import { spawn } from 'child_process';
2
2
  import { randomUUID } from 'crypto';
3
+ import { CLAUDE_PATH } from '../claudePath.js';
3
4
  // === Opus Worker (persistent, for direct mode) ===
4
5
  const OPUS_SYSTEM_PROMPT = `You are Gekto, a friendly and capable coding assistant. You help users with their coding tasks directly.
5
6
 
@@ -51,11 +52,10 @@ function spawnOpus() {
51
52
  '--disallowed-tools', 'Bash', 'Task',
52
53
  '--session-id', gektoSessionId,
53
54
  ];
54
- opusProcess = spawn('claude', args, {
55
+ opusProcess = spawn(CLAUDE_PATH, args, {
55
56
  cwd: workingDir,
56
57
  env: process.env,
57
58
  stdio: ['pipe', 'pipe', 'pipe'],
58
- shell: true,
59
59
  });
60
60
  opusProcess.stdout.on('data', (data) => {
61
61
  opusBuffer += data.toString();
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'child_process';
2
+ import { CLAUDE_PATH } from '../claudePath.js';
2
3
  // Simple Gekto - just chat with Haiku and return text response
3
4
  const GEKTO_SYSTEM_PROMPT = `You are Gekto, a friendly coding assistant. Decide what to do with the user's message.
4
5
 
@@ -59,11 +60,10 @@ function runHaiku(prompt, systemPrompt, workingDir) {
59
60
  '--system-prompt', systemPrompt,
60
61
  '--dangerously-skip-permissions',
61
62
  ];
62
- const proc = spawn('claude', args, {
63
+ const proc = spawn(CLAUDE_PATH, args, {
63
64
  cwd: workingDir,
64
65
  env: process.env,
65
66
  stdio: ['pipe', 'pipe', 'pipe'],
66
- shell: true,
67
67
  });
68
68
  proc.stdin?.end();
69
69
  let buffer = '';
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'child_process';
2
+ import { CLAUDE_PATH } from '../claudePath.js';
2
3
  // === Tool Definitions ===
3
4
  const TOOLS_DESCRIPTION = `
4
5
  Available tools:
@@ -142,11 +143,10 @@ function runClaudeOnce(prompt, systemPrompt, workingDir, callbacks) {
142
143
  '--system-prompt', systemPrompt,
143
144
  '--dangerously-skip-permissions',
144
145
  ];
145
- const proc = spawn('claude', args, {
146
+ const proc = spawn(CLAUDE_PATH, args, {
146
147
  cwd: workingDir,
147
148
  env: process.env,
148
149
  stdio: ['pipe', 'pipe', 'pipe'],
149
- shell: true,
150
150
  });
151
151
  proc.stdin?.end();
152
152
  let buffer = '';
@@ -0,0 +1,48 @@
1
+ import fs from 'fs';
2
+ import { execSync } from 'child_process';
3
+ // Find claude CLI path - check common locations for Homebrew and global npm
4
+ function findClaudePath() {
5
+ const commonPaths = [
6
+ '/opt/homebrew/bin/claude', // macOS Apple Silicon Homebrew
7
+ '/usr/local/bin/claude', // macOS Intel Homebrew / Linux
8
+ '/usr/bin/claude', // System install
9
+ `${process.env.HOME}/.npm-global/bin/claude`, // npm global (custom)
10
+ `${process.env.HOME}/.local/bin/claude`, // pip/pipx style
11
+ ];
12
+ // Try 'which' command first (works on Unix-like systems)
13
+ try {
14
+ const result = execSync('which claude', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
15
+ const claudePath = result.trim();
16
+ if (claudePath && fs.existsSync(claudePath)) {
17
+ return claudePath;
18
+ }
19
+ }
20
+ catch {
21
+ // which failed, try common paths
22
+ }
23
+ // Try 'where' command on Windows
24
+ try {
25
+ const result = execSync('where claude', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
26
+ const claudePath = result.trim().split('\n')[0];
27
+ if (claudePath && fs.existsSync(claudePath)) {
28
+ return claudePath;
29
+ }
30
+ }
31
+ catch {
32
+ // where failed, try common paths
33
+ }
34
+ // Check common paths
35
+ for (const p of commonPaths) {
36
+ if (fs.existsSync(p)) {
37
+ return p;
38
+ }
39
+ }
40
+ // Fallback to just 'claude' and hope it's in PATH
41
+ return 'claude';
42
+ }
43
+ // Resolve claude path at startup and export for other modules
44
+ export const CLAUDE_PATH = findClaudePath();
45
+ // Verify claude is accessible
46
+ if (CLAUDE_PATH === 'claude') {
47
+ console.warn('⚠️ Claude CLI not found in common paths. Make sure it\'s installed and in PATH.');
48
+ }
package/dist/proxy.js CHANGED
@@ -7,6 +7,9 @@ import { parseArgs } from 'util';
7
7
  import { setupTerminalWebSocket } from './terminal.js';
8
8
  import { setupAgentWebSocket } from './agents/agentWebSocket.js';
9
9
  import { initStore, getData, setData } from './store.js';
10
+ import { CLAUDE_PATH } from './claudePath.js';
11
+ // Re-export for backwards compatibility
12
+ export { CLAUDE_PATH };
10
13
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
14
  // Parse CLI arguments
12
15
  const { values: args } = parseArgs({
@@ -35,7 +38,7 @@ if (args.help) {
35
38
  // Only require --target for bundled version (not dev mode)
36
39
  if (!args.target && !process.env.TARGET_PORT && !process.env.GEKTO_DEV) {
37
40
  console.error('Error: --target port is required\n');
38
- console.error('Usage: bun gekto.ts --target 3000');
41
+ console.error('Usage: npx gekto --target 3000');
39
42
  process.exit(1);
40
43
  }
41
44
  // Configuration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gekto",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "AI coding assistant widget - inject into any web app",
5
5
  "type": "module",
6
6
  "bin": {