@aptove/aptove 0.1.8 → 0.1.10
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/aptove +35 -48
- package/package.json +6 -6
- package/postinstall.js +122 -67
package/bin/aptove
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* aptove - ACP AI coding agent
|
|
5
|
-
*
|
|
6
|
-
* This script finds and executes the platform-specific binary.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { execFileSync } = require('child_process');
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
10
4
|
const path = require('path');
|
|
11
5
|
const fs = require('fs');
|
|
12
6
|
|
|
@@ -18,60 +12,53 @@ const PLATFORM_PACKAGES = {
|
|
|
18
12
|
'win32-x64': '@aptove/aptove-win32-x64',
|
|
19
13
|
};
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const packageName = PLATFORM_PACKAGES[platformKey];
|
|
15
|
+
const platformKey = `${process.platform}-${process.arch}`;
|
|
16
|
+
const packageName = PLATFORM_PACKAGES[platformKey];
|
|
24
17
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
if (!packageName) {
|
|
19
|
+
console.error(`aptove: unsupported platform ${platformKey}`);
|
|
20
|
+
console.error('Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64, win32-x64');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
const binaryName = process.platform === 'win32' ? 'aptove.exe' : 'aptove';
|
|
32
25
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
path.join(__dirname, '..', 'node_modules', packageName, 'bin', binaryName),
|
|
40
|
-
];
|
|
26
|
+
// Both @aptove/aptove and @aptove/aptove-<platform> live under the same
|
|
27
|
+
// @aptove scope directory, so the platform package is always a sibling:
|
|
28
|
+
// __dirname = .../node_modules/@aptove/aptove/bin
|
|
29
|
+
// platform = .../node_modules/@aptove/aptove-darwin-arm64/bin/aptove
|
|
30
|
+
const shortName = packageName.split('/')[1]; // e.g. "aptove-darwin-arm64"
|
|
31
|
+
const siblingPath = path.join(__dirname, '..', '..', shortName, 'bin', binaryName);
|
|
41
32
|
|
|
42
|
-
|
|
43
|
-
if (fs.existsSync(binaryPath)) {
|
|
44
|
-
return binaryPath;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
33
|
+
let binaryPath = fs.existsSync(siblingPath) ? siblingPath : null;
|
|
47
34
|
|
|
48
|
-
|
|
35
|
+
// Fallback: require.resolve handles pnpm virtual stores and other layouts
|
|
36
|
+
if (!binaryPath) {
|
|
49
37
|
try {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
if (fs.existsSync(
|
|
53
|
-
|
|
38
|
+
const pkgJson = require.resolve(`${packageName}/package.json`);
|
|
39
|
+
const candidate = path.join(path.dirname(pkgJson), 'bin', binaryName);
|
|
40
|
+
if (fs.existsSync(candidate)) {
|
|
41
|
+
binaryPath = candidate;
|
|
54
42
|
}
|
|
55
43
|
} catch (e) {
|
|
56
|
-
//
|
|
44
|
+
// not found
|
|
57
45
|
}
|
|
46
|
+
}
|
|
58
47
|
|
|
59
|
-
|
|
60
|
-
console.error(`
|
|
48
|
+
if (!binaryPath) {
|
|
49
|
+
console.error(`aptove: platform package not installed for ${platformKey}`);
|
|
61
50
|
console.error('');
|
|
62
|
-
console.error('
|
|
63
|
-
console.error(
|
|
51
|
+
console.error('Run:');
|
|
52
|
+
console.error(` npm install -g ${packageName}`);
|
|
64
53
|
process.exit(1);
|
|
65
54
|
}
|
|
66
55
|
|
|
67
|
-
const
|
|
68
|
-
const args = process.argv.slice(2);
|
|
56
|
+
const result = spawnSync(binaryPath, process.argv.slice(2), { stdio: 'inherit' });
|
|
69
57
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
process.exit(error.status);
|
|
75
|
-
}
|
|
76
|
-
throw error;
|
|
58
|
+
if (result.error) {
|
|
59
|
+
console.error(`aptove: failed to execute binary: ${result.error.message}`);
|
|
60
|
+
console.error(` Binary: ${binaryPath}`);
|
|
61
|
+
process.exit(1);
|
|
77
62
|
}
|
|
63
|
+
|
|
64
|
+
process.exit(result.status ?? 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aptove/aptove",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "ACP AI coding agent — connects to Claude, Gemini, and OpenAI",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"node": ">=16"
|
|
36
36
|
},
|
|
37
37
|
"optionalDependencies": {
|
|
38
|
-
"@aptove/aptove-darwin-arm64": "0.1.
|
|
39
|
-
"@aptove/aptove-darwin-x64": "0.1.
|
|
40
|
-
"@aptove/aptove-linux-arm64": "0.1.
|
|
41
|
-
"@aptove/aptove-linux-x64": "0.1.
|
|
42
|
-
"@aptove/aptove-win32-x64": "0.1.
|
|
38
|
+
"@aptove/aptove-darwin-arm64": "0.1.10",
|
|
39
|
+
"@aptove/aptove-darwin-x64": "0.1.10",
|
|
40
|
+
"@aptove/aptove-linux-arm64": "0.1.10",
|
|
41
|
+
"@aptove/aptove-linux-x64": "0.1.10",
|
|
42
|
+
"@aptove/aptove-win32-x64": "0.1.10"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/postinstall.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* aptove postinstall script
|
|
3
3
|
*
|
|
4
|
-
* Ensures the
|
|
5
|
-
* npm sometimes skips optional dependencies during global installs, so
|
|
6
|
-
*
|
|
4
|
+
* Ensures the platform-specific binary package is installed at the correct version.
|
|
5
|
+
* npm sometimes skips optional dependencies during global installs, so we detect
|
|
6
|
+
* this and install the platform package explicitly if needed.
|
|
7
|
+
* Validates the final binary by running it with --version.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
const { execSync } = require('child_process');
|
|
10
|
+
const { execSync, spawnSync } = require('child_process');
|
|
10
11
|
const path = require('path');
|
|
11
12
|
const fs = require('fs');
|
|
12
13
|
|
|
@@ -18,96 +19,150 @@ const PLATFORM_PACKAGES = {
|
|
|
18
19
|
'win32-x64': '@aptove/aptove-win32-x64',
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
return { platformKey, packageName: PLATFORM_PACKAGES[platformKey] };
|
|
22
|
+
function isBinaryPresent(binaryPath) {
|
|
23
|
+
return fs.existsSync(binaryPath);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
function isBinaryInstalled(packageName) {
|
|
26
|
+
// Ensures the binary has executable permissions (no-op on Windows).
|
|
27
|
+
function ensureExecutable(binaryPath) {
|
|
28
|
+
if (process.platform === 'win32') return;
|
|
30
29
|
try {
|
|
31
|
-
|
|
32
|
-
return fs.existsSync(path.join(path.dirname(packagePath), 'bin', BINARY_NAME));
|
|
30
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
33
31
|
} catch (e) {
|
|
34
|
-
|
|
32
|
+
// best-effort
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return fs.existsSync(path.join(packageDir, 'bin', BINARY_NAME));
|
|
36
|
+
// Returns the version string from `aptove --version` (e.g. "0.1.9"), or null on failure.
|
|
37
|
+
function getBinaryVersion(binaryPath) {
|
|
38
|
+
const result = spawnSync(binaryPath, ['--version'], { stdio: 'pipe' });
|
|
39
|
+
if (result.error || result.status !== 0) return null;
|
|
40
|
+
const output = (result.stdout || '').toString().trim(); // e.g. "aptove 0.1.9"
|
|
41
|
+
const parts = output.split(' ');
|
|
42
|
+
return parts.length >= 2 ? parts[1] : output;
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
// Reads the expected platform package version from the main package's optionalDependencies.
|
|
46
|
+
function getExpectedVersion(packageJsonPath) {
|
|
49
47
|
try {
|
|
50
|
-
|
|
48
|
+
delete require.cache[require.resolve(packageJsonPath)];
|
|
49
|
+
const pkg = require(packageJsonPath);
|
|
51
50
|
// optionalDependencies values are updated by the release workflow to match the published version
|
|
52
51
|
const deps = pkg.optionalDependencies || {};
|
|
53
52
|
const versions = Object.values(deps).filter(v => v !== '*');
|
|
54
53
|
return versions[0] || pkg.version;
|
|
55
54
|
} catch (e) {
|
|
56
|
-
return
|
|
55
|
+
return null;
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
function main(
|
|
74
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Main postinstall logic.
|
|
61
|
+
*
|
|
62
|
+
* All I/O is injectable for testing:
|
|
63
|
+
* baseDir — replaces __dirname for computing the sibling binary path
|
|
64
|
+
* packageJsonPath— path to the main package's package.json
|
|
65
|
+
* platformKey — override platform detection (default: process.platform-process.arch)
|
|
66
|
+
* npmPrefix — override npm_config_prefix
|
|
67
|
+
* installFn — (packageName, version) => void; throws on failure
|
|
68
|
+
* defaults to running `npm install` via execSync
|
|
69
|
+
* log / warn — console.log / console.warn replacements
|
|
70
|
+
* exitFn — process.exit replacement
|
|
71
|
+
*/
|
|
72
|
+
function main({
|
|
73
|
+
baseDir = __dirname,
|
|
74
|
+
packageJsonPath = path.join(__dirname, 'package.json'),
|
|
75
|
+
platformKey = `${process.platform}-${process.arch}`,
|
|
76
|
+
npmPrefix = process.env.npm_config_prefix,
|
|
77
|
+
installFn = null,
|
|
78
|
+
log = (...a) => console.log(...a),
|
|
79
|
+
warn = (...a) => console.warn(...a),
|
|
80
|
+
exitFn = process.exit,
|
|
81
|
+
} = {}) {
|
|
82
|
+
const packageName = PLATFORM_PACKAGES[platformKey];
|
|
75
83
|
|
|
76
84
|
if (!packageName) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return;
|
|
85
|
+
warn(`⚠️ aptove: unsupported platform ${platformKey}`);
|
|
86
|
+
exitFn(0); return;
|
|
80
87
|
}
|
|
81
88
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
const binaryName = process.platform === 'win32' ? 'aptove.exe' : 'aptove';
|
|
90
|
+
const shortName = packageName.split('/')[1]; // e.g. "aptove-darwin-arm64"
|
|
91
|
+
|
|
92
|
+
// postinstall.js lives at @aptove/aptove/postinstall.js
|
|
93
|
+
// platform binary lives at @aptove/aptove-darwin-arm64/bin/aptove (sibling package)
|
|
94
|
+
const siblingBinaryPath = path.join(baseDir, '..', shortName, 'bin', binaryName);
|
|
95
|
+
|
|
96
|
+
function tryInstall(version) {
|
|
97
|
+
const fn = installFn || ((pkg, ver) => {
|
|
98
|
+
const prefixFlag = npmPrefix ? `--prefix "${npmPrefix}"` : '';
|
|
99
|
+
execSync(
|
|
100
|
+
`npm install ${prefixFlag} --no-save --no-audit --no-fund "${pkg}@${ver}"`,
|
|
101
|
+
{ stdio: 'inherit' }
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
try {
|
|
105
|
+
log(` Installing ${packageName}@${version}...`);
|
|
106
|
+
fn(packageName, version);
|
|
107
|
+
// GitHub artifact uploads strip execute permissions; restore them.
|
|
108
|
+
if (isBinaryPresent(siblingBinaryPath)) ensureExecutable(siblingBinaryPath);
|
|
109
|
+
return true;
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
85
113
|
}
|
|
86
114
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
115
|
+
const expectedVersion = getExpectedVersion(packageJsonPath);
|
|
116
|
+
|
|
117
|
+
if (isBinaryPresent(siblingBinaryPath)) {
|
|
118
|
+
// Fix permissions in case the binary was published without the execute bit
|
|
119
|
+
// (GitHub Actions artifacts do not preserve file permissions).
|
|
120
|
+
ensureExecutable(siblingBinaryPath);
|
|
121
|
+
const installedVersion = getBinaryVersion(siblingBinaryPath);
|
|
122
|
+
if (installedVersion && expectedVersion && installedVersion !== expectedVersion) {
|
|
123
|
+
log(`⬆ aptove: updating platform binary ${installedVersion} → ${expectedVersion}...`);
|
|
124
|
+
if (!tryInstall(expectedVersion)) {
|
|
125
|
+
warn(`⚠️ aptove: update failed — run: npm install -g ${packageName}@${expectedVersion}`);
|
|
126
|
+
exitFn(0); return;
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
log(`✓ aptove ${installedVersion || '(unknown)'} installed successfully for ${platformKey}`);
|
|
130
|
+
exitFn(0); return;
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
log(`\n⬇ aptove: platform binary not found, installing ${packageName}...`);
|
|
134
|
+
if (!tryInstall(expectedVersion || 'latest')) {
|
|
135
|
+
warn(`\n⚠️ aptove: failed to install ${packageName}`);
|
|
136
|
+
warn(` Run manually: npm install -g ${packageName}${expectedVersion ? '@' + expectedVersion : ''}`);
|
|
137
|
+
exitFn(0); return;
|
|
138
|
+
}
|
|
99
139
|
}
|
|
100
140
|
|
|
101
|
-
//
|
|
102
|
-
// require.resolve cannot be used here
|
|
103
|
-
//
|
|
104
|
-
if (
|
|
105
|
-
|
|
141
|
+
// Validate after install using sibling path directly.
|
|
142
|
+
// (require.resolve cannot be used here — Node.js caches negative module
|
|
143
|
+
// resolution results within the same process.)
|
|
144
|
+
if (isBinaryPresent(siblingBinaryPath)) {
|
|
145
|
+
ensureExecutable(siblingBinaryPath);
|
|
146
|
+
const installedVersion = getBinaryVersion(siblingBinaryPath);
|
|
147
|
+
if (installedVersion) {
|
|
148
|
+
if (expectedVersion && installedVersion !== expectedVersion) {
|
|
149
|
+
warn(`⚠️ aptove: installed ${installedVersion} but expected ${expectedVersion} (may not be published yet)`);
|
|
150
|
+
} else {
|
|
151
|
+
log(`✓ aptove ${installedVersion} installed successfully for ${platformKey}`);
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
warn(`⚠️ aptove: binary present but failed to run — try: ${siblingBinaryPath} --version`);
|
|
155
|
+
}
|
|
106
156
|
} else {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
process.exit(1);
|
|
157
|
+
warn(`\n⚠️ aptove: binary not found after installation`);
|
|
158
|
+
warn(` Run manually: npm install -g ${packageName}${expectedVersion ? '@' + expectedVersion : ''}`);
|
|
110
159
|
}
|
|
160
|
+
|
|
161
|
+
exitFn(0);
|
|
111
162
|
}
|
|
112
163
|
|
|
113
|
-
main
|
|
164
|
+
module.exports = { main, PLATFORM_PACKAGES, isBinaryPresent, ensureExecutable, getBinaryVersion, getExpectedVersion };
|
|
165
|
+
|
|
166
|
+
if (require.main === module) {
|
|
167
|
+
main();
|
|
168
|
+
}
|