agent-notify 0.1.1
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/bin/agent-notify.js +56 -0
- package/package.json +34 -0
- package/scripts/install.js +161 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
|
|
9
|
+
function getBinaryDir() {
|
|
10
|
+
// Try to get npm global bin directory
|
|
11
|
+
// npm bin -g is deprecated, use npm prefix -g instead
|
|
12
|
+
try {
|
|
13
|
+
const prefix = execSync('npm prefix -g', { encoding: 'utf8' }).trim();
|
|
14
|
+
return path.join(prefix, 'bin');
|
|
15
|
+
} catch (e) {
|
|
16
|
+
// Fallback to ~/.local/bin
|
|
17
|
+
return path.join(os.homedir(), '.local', 'bin');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const BINARY_DIR = getBinaryDir();
|
|
22
|
+
|
|
23
|
+
function getBinaryName() {
|
|
24
|
+
return os.platform() === 'win32' ? 'agent-notify.exe' : 'agent-notify';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getBinaryPath() {
|
|
28
|
+
return path.join(BINARY_DIR, getBinaryName());
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function run() {
|
|
32
|
+
const binaryPath = getBinaryPath();
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(binaryPath)) {
|
|
35
|
+
console.error(`Binary not found at ${binaryPath}`);
|
|
36
|
+
console.error('Please run: npm install or npx @hellolib/agent-notify');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const args = process.argv.slice(2);
|
|
41
|
+
const child = spawn(binaryPath, args, {
|
|
42
|
+
stdio: 'inherit',
|
|
43
|
+
env: process.env
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
child.on('exit', (code) => {
|
|
47
|
+
process.exit(code || 0);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
child.on('error', (err) => {
|
|
51
|
+
console.error(`Failed to run binary: ${err.message}`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
run();
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-notify",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Agent notification tool with Feishu integration",
|
|
5
|
+
"bin": {
|
|
6
|
+
"agent-notify": "./bin/agent-notify.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/install.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"scripts/"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"claude",
|
|
17
|
+
"notification",
|
|
18
|
+
"feishu",
|
|
19
|
+
"agent"
|
|
20
|
+
],
|
|
21
|
+
"author": "hellolib",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/hellolib/agent-notify.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/hellolib/agent-notify/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/hellolib/agent-notify#readme",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=14"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const http = require('http');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
|
|
10
|
+
const PACKAGE_VERSION = require('../package.json').version;
|
|
11
|
+
const GITHUB_REPO = 'hellolib/agent-notify';
|
|
12
|
+
|
|
13
|
+
function getBinaryDir() {
|
|
14
|
+
// Try to get npm global bin directory
|
|
15
|
+
// npm bin -g is deprecated, use npm prefix -g instead
|
|
16
|
+
try {
|
|
17
|
+
const prefix = execSync('npm prefix -g', { encoding: 'utf8' }).trim();
|
|
18
|
+
return path.join(prefix, 'bin');
|
|
19
|
+
} catch (e) {
|
|
20
|
+
// Fallback to ~/.local/bin
|
|
21
|
+
return path.join(os.homedir(), '.local', 'bin');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const BINARY_DIR = getBinaryDir();
|
|
26
|
+
|
|
27
|
+
function getRemoteBinaryName(version) {
|
|
28
|
+
const platform = os.platform();
|
|
29
|
+
const arch = os.arch();
|
|
30
|
+
|
|
31
|
+
const platformMap = {
|
|
32
|
+
darwin: 'darwin',
|
|
33
|
+
linux: 'linux',
|
|
34
|
+
win32: 'windows'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const archMap = {
|
|
38
|
+
x64: 'amd64',
|
|
39
|
+
arm64: 'arm64'
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const mappedPlatform = platformMap[platform];
|
|
43
|
+
const mappedArch = archMap[arch];
|
|
44
|
+
|
|
45
|
+
if (!mappedPlatform || !mappedArch) {
|
|
46
|
+
throw new Error(`Unsupported platform: ${platform} ${arch}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const binaryName = platform === 'win32'
|
|
50
|
+
? `agent-notify-v${version}-${mappedPlatform}-${mappedArch}.exe`
|
|
51
|
+
: `agent-notify-v${version}-${mappedPlatform}-${mappedArch}`;
|
|
52
|
+
|
|
53
|
+
return binaryName;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getLocalBinaryName() {
|
|
57
|
+
return os.platform() === 'win32' ? 'agent-notify.exe' : 'agent-notify';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getDownloadUrl(binaryName, version) {
|
|
61
|
+
return `https://github.com/${GITHUB_REPO}/releases/download/v${version}/${binaryName}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function downloadFile(url, dest) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const protocol = url.startsWith('https') ? https : http;
|
|
67
|
+
|
|
68
|
+
console.log(`Downloading: ${url}`);
|
|
69
|
+
|
|
70
|
+
const request = protocol.get(url, (response) => {
|
|
71
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
72
|
+
downloadFile(response.headers.location, dest).then(resolve).catch(reject);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (response.statusCode !== 200) {
|
|
77
|
+
reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const totalSize = parseInt(response.headers['content-length'], 10);
|
|
82
|
+
let downloadedSize = 0;
|
|
83
|
+
let lastPercent = 0;
|
|
84
|
+
|
|
85
|
+
const file = fs.createWriteStream(dest);
|
|
86
|
+
|
|
87
|
+
response.on('data', (chunk) => {
|
|
88
|
+
downloadedSize += chunk.length;
|
|
89
|
+
if (totalSize) {
|
|
90
|
+
const percent = Math.floor((downloadedSize / totalSize) * 100);
|
|
91
|
+
if (percent >= lastPercent + 10) {
|
|
92
|
+
process.stdout.write(`\rDownloading: ${percent}%`);
|
|
93
|
+
lastPercent = percent;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
response.pipe(file);
|
|
99
|
+
|
|
100
|
+
file.on('finish', () => {
|
|
101
|
+
file.close();
|
|
102
|
+
process.stdout.write('\n');
|
|
103
|
+
resolve();
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
request.on('error', (err) => {
|
|
108
|
+
fs.unlink(dest, () => {});
|
|
109
|
+
reject(err);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
request.setTimeout(120000, () => {
|
|
113
|
+
request.destroy();
|
|
114
|
+
reject(new Error('Download timeout'));
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function install() {
|
|
120
|
+
const remoteBinaryName = getRemoteBinaryName(PACKAGE_VERSION);
|
|
121
|
+
const localBinaryName = getLocalBinaryName();
|
|
122
|
+
const binaryPath = path.join(BINARY_DIR, localBinaryName);
|
|
123
|
+
|
|
124
|
+
// Check if binary already exists
|
|
125
|
+
if (fs.existsSync(binaryPath)) {
|
|
126
|
+
console.log(`Binary already exists at ${binaryPath}`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Create binary directory
|
|
131
|
+
if (!fs.existsSync(BINARY_DIR)) {
|
|
132
|
+
fs.mkdirSync(BINARY_DIR, { recursive: true });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const url = getDownloadUrl(remoteBinaryName, PACKAGE_VERSION);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
await downloadFile(url, binaryPath);
|
|
139
|
+
|
|
140
|
+
// Make binary executable (Unix)
|
|
141
|
+
if (os.platform() !== 'win32') {
|
|
142
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
console.log(`Successfully installed binary to ${binaryPath}`);
|
|
146
|
+
console.log(`Ensure ${BINARY_DIR} is in your PATH.`);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
console.error(`Failed to download binary: ${err.message}`);
|
|
149
|
+
console.error('');
|
|
150
|
+
console.error('Please ensure the release exists at:');
|
|
151
|
+
console.error(` ${url}`);
|
|
152
|
+
|
|
153
|
+
// Don't fail the install, let user download manually
|
|
154
|
+
process.exit(0);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
install().catch((err) => {
|
|
159
|
+
console.error(err.message);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
});
|