@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 +58 -0
- package/package.json +44 -0
- package/scripts/install.js +121 -0
- package/scripts/release.js +37 -0
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!`);
|