@diggerhq/catty 0.2.15

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 ADDED
@@ -0,0 +1,58 @@
1
+ # Catty
2
+
3
+ Run Claude Code sessions remotely.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @izalutski/catty
9
+ ```
10
+
11
+ Or use directly with npx:
12
+
13
+ ```bash
14
+ npx @izalutski/catty new
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### First-time setup
20
+
21
+ ```bash
22
+ # Log in (required once)
23
+ catty login
24
+ ```
25
+
26
+ ### Start a new Claude Code session
27
+
28
+ ```bash
29
+ catty new
30
+ ```
31
+
32
+ This will:
33
+ 1. Upload your current directory to a remote machine
34
+ 2. Start Claude Code in the remote environment
35
+ 3. Connect you to an interactive terminal session
36
+
37
+ ### Commands
38
+
39
+ ```bash
40
+ catty login # Authenticate (required before first use)
41
+ catty logout # Remove stored credentials
42
+ catty new # Start Claude Code (default)
43
+ catty new --no-upload # Don't upload current directory
44
+ catty list # List active sessions
45
+ catty stop <session-id> # Stop a session
46
+ ```
47
+
48
+ ## Requirements
49
+
50
+ - Node.js 16+
51
+
52
+ ## How it works
53
+
54
+ Catty creates isolated machines on-demand, uploads your workspace, and streams the terminal to you. Each session is isolated and secure.
55
+
56
+ ## License
57
+
58
+ MIT
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@diggerhq/catty",
3
+ "version": "0.2.15",
4
+ "description": "Run Claude Code sessions remotely",
5
+ "keywords": [
6
+ "ai",
7
+ "claude",
8
+ "agent",
9
+ "remote",
10
+ "terminal",
11
+ "code"
12
+ ],
13
+ "author": "izalutski",
14
+ "license": "MIT",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/diggerhq/catty.git"
18
+ },
19
+ "bin": {
20
+ "catty": "./bin/catty"
21
+ },
22
+ "scripts": {
23
+ "postinstall": "node scripts/install.js",
24
+ "release": "node scripts/release.js patch",
25
+ "release:patch": "node scripts/release.js patch",
26
+ "release:minor": "node scripts/release.js minor",
27
+ "release:major": "node scripts/release.js major"
28
+ },
29
+ "files": [
30
+ "scripts"
31
+ ],
32
+ "engines": {
33
+ "node": ">=16"
34
+ },
35
+ "os": [
36
+ "darwin",
37
+ "linux",
38
+ "win32"
39
+ ],
40
+ "cpu": [
41
+ "x64",
42
+ "arm64"
43
+ ]
44
+ }
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+
3
+ const https = require('https');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const { execSync } = require('child_process');
7
+
8
+ const packageJson = require('../package.json');
9
+ const VERSION = process.env.CATTY_VERSION || packageJson.version;
10
+ const GITHUB_REPO = 'diggerhq/catty';
11
+
12
+ function getPlatform() {
13
+ const platform = process.platform;
14
+ const arch = process.arch;
15
+
16
+ const platformMap = {
17
+ darwin: 'darwin',
18
+ linux: 'linux',
19
+ win32: 'windows',
20
+ };
21
+
22
+ const archMap = {
23
+ x64: 'amd64',
24
+ arm64: 'arm64',
25
+ };
26
+
27
+ const os = platformMap[platform];
28
+ const cpu = archMap[arch];
29
+
30
+ if (!os || !cpu) {
31
+ throw new Error(`Unsupported platform: ${platform}-${arch}`);
32
+ }
33
+
34
+ return { os, cpu, platform, arch };
35
+ }
36
+
37
+ function getBinaryName(os) {
38
+ return os === 'windows' ? 'catty.exe' : 'catty';
39
+ }
40
+
41
+ function getDownloadUrl(os, cpu) {
42
+ const ext = os === 'windows' ? '.exe' : '';
43
+ return `https://github.com/${GITHUB_REPO}/releases/download/v${VERSION}/catty-${os}-${cpu}${ext}`;
44
+ }
45
+
46
+ function download(url, dest) {
47
+ return new Promise((resolve, reject) => {
48
+ const file = fs.createWriteStream(dest);
49
+
50
+ const request = (url) => {
51
+ https.get(url, (response) => {
52
+ // Handle redirects
53
+ if (response.statusCode === 302 || response.statusCode === 301) {
54
+ request(response.headers.location);
55
+ return;
56
+ }
57
+
58
+ if (response.statusCode !== 200) {
59
+ reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
60
+ return;
61
+ }
62
+
63
+ response.pipe(file);
64
+ file.on('finish', () => {
65
+ file.close(resolve);
66
+ });
67
+ }).on('error', (err) => {
68
+ fs.unlink(dest, () => {});
69
+ reject(err);
70
+ });
71
+ };
72
+
73
+ request(url);
74
+ });
75
+ }
76
+
77
+ async function install() {
78
+ try {
79
+ const { os, cpu, platform } = getPlatform();
80
+ const binaryName = getBinaryName(os);
81
+ const binDir = path.join(__dirname, '..', 'bin');
82
+ const binaryPath = path.join(binDir, binaryName);
83
+
84
+ // Create bin directory if it doesn't exist
85
+ if (!fs.existsSync(binDir)) {
86
+ fs.mkdirSync(binDir, { recursive: true });
87
+ }
88
+
89
+ // Check if binary already exists and is actually a binary (not placeholder)
90
+ if (fs.existsSync(binaryPath)) {
91
+ const stats = fs.statSync(binaryPath);
92
+ // Placeholder is ~300 bytes, real binary is much larger
93
+ if (stats.size > 1000) {
94
+ console.log('catty binary already installed');
95
+ return;
96
+ }
97
+ // Remove placeholder
98
+ fs.unlinkSync(binaryPath);
99
+ }
100
+
101
+ const url = getDownloadUrl(os, cpu);
102
+ console.log(`Downloading catty from ${url}...`);
103
+
104
+ await download(url, binaryPath);
105
+
106
+ // Make executable on Unix
107
+ if (platform !== 'win32') {
108
+ fs.chmodSync(binaryPath, 0o755);
109
+ }
110
+
111
+ console.log('catty installed successfully!');
112
+ } catch (error) {
113
+ console.error('Failed to install catty:', error.message);
114
+ console.error('');
115
+ console.error('You can manually download the binary from:');
116
+ console.error(`https://github.com/${GITHUB_REPO}/releases`);
117
+ process.exit(1);
118
+ }
119
+ }
120
+
121
+ install();
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require('child_process');
4
+ const path = require('path');
5
+
6
+ const rootDir = path.join(__dirname, '..', '..');
7
+ const npmDir = path.join(__dirname, '..');
8
+
9
+ function run(cmd, cwd = rootDir) {
10
+ console.log(`> ${cmd}`);
11
+ execSync(cmd, { cwd, stdio: 'inherit' });
12
+ }
13
+
14
+ const versionType = process.argv[2] || 'patch';
15
+ if (!['patch', 'minor', 'major'].includes(versionType)) {
16
+ console.error('Usage: node scripts/release.js [patch|minor|major]');
17
+ process.exit(1);
18
+ }
19
+
20
+ // 1. Bump version
21
+ run(`npm version ${versionType} --no-git-tag-version`, npmDir);
22
+
23
+ // 2. Get new version
24
+ const packageJson = require('../package.json');
25
+ const version = packageJson.version;
26
+ console.log(`\nReleasing v${version}...\n`);
27
+
28
+ // 3. Build binaries (pass version to Makefile)
29
+ run(`make release VERSION=${version}`);
30
+
31
+ // 4. Create GitHub release
32
+ run(`gh release create v${version} dist/* --title "v${version}" --notes "Release v${version}"`);
33
+
34
+ // 5. Publish to npm
35
+ run('npm publish --access public', npmDir);
36
+
37
+ console.log(`\nReleased v${version} successfully!`);