Skip to content

Commit 29081ee

Browse files
Fix npx bootstrap: non-fatal postinstall and binary fallback
1 parent 4b62638 commit 29081ee

5 files changed

Lines changed: 44 additions & 9 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "attn"
3-
version = "0.1.16"
3+
version = "0.1.17"
44
edition = "2024"
55
description = "A beautiful markdown viewer that launches from the CLI"
66
license = "MIT"

bin/attn.js

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const {
44
chmodSync,
5-
copyFileSync,
65
createWriteStream,
76
existsSync,
87
mkdirSync,
@@ -58,10 +57,29 @@ async function main() {
5857
const args = process.argv.slice(2);
5958
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
6059
const version = packageJson.version;
61-
62-
const appPath = await resolveAppPath(version);
6360
const headless = isHeadlessInvocation(args);
6461

62+
let appPath = null;
63+
try {
64+
appPath = await resolveAppPath(version);
65+
} catch (error) {
66+
console.error(`attn: app install unavailable (${error.message}); falling back to binary.`);
67+
}
68+
69+
if (!appPath) {
70+
if (!existsSync(runtimeBinaryPath)) {
71+
await ensureRuntimeBinary(version);
72+
}
73+
if (!existsSync(runtimeBinaryPath)) {
74+
throw new Error("runtime binary is missing after fallback download attempt.");
75+
}
76+
if (isNpxInvocation) {
77+
await maybePromptInstallAlias();
78+
}
79+
run(runtimeBinaryPath, args);
80+
return;
81+
}
82+
6583
if (isNpxInvocation) {
6684
await maybePromptInstallAlias();
6785
}
@@ -100,6 +118,23 @@ async function resolveAppPath(version) {
100118
return managedVersionApp;
101119
}
102120

121+
async function ensureRuntimeBinary(version) {
122+
const assetSuffix = resolveAssetSuffix(process.platform, process.arch);
123+
if (!assetSuffix) {
124+
throw new Error(
125+
`unsupported platform ${process.platform}/${process.arch}. Currently supported: darwin-arm64.`
126+
);
127+
}
128+
129+
const url = `https://github.com/lightsofapollo/attn/releases/download/v${version}/attn-v${version}-${assetSuffix}`;
130+
const tempPath = `${runtimeBinaryPath}.tmp`;
131+
mkdirSync(runtimeDir, { recursive: true });
132+
await download(url, tempPath);
133+
chmodSync(tempPath, 0o755);
134+
renameSync(tempPath, runtimeBinaryPath);
135+
console.error(`attn: installed runtime binary ${runtimeBinaryPath}`);
136+
}
137+
103138
function findGlobalAppInstall() {
104139
const candidates = [
105140
"/Applications/attn.app",
@@ -303,4 +338,3 @@ function download(url, destination) {
303338
request.on("error", reject);
304339
});
305340
}
306-

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "attnmd",
3-
"version": "0.1.16",
3+
"version": "0.1.17",
44
"description": "A beautiful markdown viewer that launches from the CLI",
55
"license": "MIT",
66
"repository": {

scripts/postinstall.mjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ download(url, tempPath)
3939
})
4040
.catch((error) => {
4141
safeRemove(tempPath);
42-
console.error(`attn: failed to download release binary: ${error.message}`);
43-
process.exit(1);
42+
console.warn(`attn: runtime prefetch failed: ${error.message}`);
43+
console.warn("attn: continuing; runtime will be installed on first launch.");
44+
process.exit(0);
4445
});
4546

4647
function resolveAssetSuffix(platform, arch) {

0 commit comments

Comments
 (0)