@akiojin/gwt 6.30.3 → 9.0.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.
Files changed (98) hide show
  1. package/.cargo/config.toml +2 -0
  2. package/.claude-plugin/marketplace.json +18 -0
  3. package/.coderabbit.yaml +8 -0
  4. package/.codex/skills/gwt-fix-issue/scripts/inspect_issue.py +833 -0
  5. package/.dockerignore +63 -0
  6. package/.gitattributes +27 -0
  7. package/.husky/commit-msg +2 -0
  8. package/.husky/pre-commit +9 -0
  9. package/.husky/pre-push +12 -0
  10. package/.markdownlint.json +18 -0
  11. package/.markdownlintignore +2 -0
  12. package/Dockerfile +58 -0
  13. package/README.ja.md +161 -484
  14. package/README.md +164 -444
  15. package/cliff.toml +56 -0
  16. package/clippy.toml +2 -0
  17. package/cmake/ci-disable-native.cmake +16 -0
  18. package/codecov.yml +16 -0
  19. package/commitlint.config.cjs +107 -0
  20. package/deny.toml +35 -0
  21. package/docker-compose.yml +59 -0
  22. package/messages/errors.toml +52 -0
  23. package/package.json +12 -22
  24. package/rustfmt.toml +8 -0
  25. package/scripts/check-e2e-coverage-threshold.mjs +238 -0
  26. package/scripts/entrypoint.sh +36 -25
  27. package/scripts/install-linux-deps.sh +46 -0
  28. package/scripts/postinstall.js +79 -227
  29. package/scripts/release_issue_refs.py +317 -0
  30. package/scripts/run-local-backend-tests-on-commit.sh +15 -0
  31. package/scripts/run-local-e2e-coverage-on-commit.sh +69 -0
  32. package/scripts/run-local-e2e-on-commit.sh +60 -0
  33. package/scripts/test-all.sh +13 -0
  34. package/scripts/test_release_issue_refs.py +257 -0
  35. package/scripts/validate-skill-frontmatter.sh +108 -0
  36. package/scripts/verify-ci-node-toolchain.sh +76 -0
  37. package/scripts/verify-husky-hooks.sh +6 -0
  38. package/scripts/voice-eval.sh +48 -0
  39. package/tests/voice_eval/README.md +53 -0
  40. package/tests/voice_eval/manifest.template.json +55 -0
  41. package/tests/voice_eval/samples/.gitkeep +1 -0
  42. package/tests/voice_eval/script-ja.txt +10 -0
  43. package/vendor/ratatui-core/src/backend/test.rs +1077 -0
  44. package/vendor/ratatui-core/src/backend.rs +405 -0
  45. package/vendor/ratatui-core/src/buffer/assert.rs +71 -0
  46. package/vendor/ratatui-core/src/buffer/buffer.rs +1388 -0
  47. package/vendor/ratatui-core/src/buffer/cell.rs +377 -0
  48. package/vendor/ratatui-core/src/buffer.rs +9 -0
  49. package/vendor/ratatui-core/src/layout/alignment.rs +89 -0
  50. package/vendor/ratatui-core/src/layout/constraint.rs +526 -0
  51. package/vendor/ratatui-core/src/layout/direction.rs +63 -0
  52. package/vendor/ratatui-core/src/layout/flex.rs +212 -0
  53. package/vendor/ratatui-core/src/layout/layout.rs +2838 -0
  54. package/vendor/ratatui-core/src/layout/margin.rs +79 -0
  55. package/vendor/ratatui-core/src/layout/offset.rs +66 -0
  56. package/vendor/ratatui-core/src/layout/position.rs +253 -0
  57. package/vendor/ratatui-core/src/layout/rect/iter.rs +356 -0
  58. package/vendor/ratatui-core/src/layout/rect/ops.rs +136 -0
  59. package/vendor/ratatui-core/src/layout/rect.rs +1114 -0
  60. package/vendor/ratatui-core/src/layout/size.rs +147 -0
  61. package/vendor/ratatui-core/src/layout.rs +333 -0
  62. package/vendor/ratatui-core/src/lib.rs +82 -0
  63. package/vendor/ratatui-core/src/style/anstyle.rs +348 -0
  64. package/vendor/ratatui-core/src/style/color.rs +788 -0
  65. package/vendor/ratatui-core/src/style/palette/material.rs +608 -0
  66. package/vendor/ratatui-core/src/style/palette/tailwind.rs +653 -0
  67. package/vendor/ratatui-core/src/style/palette.rs +6 -0
  68. package/vendor/ratatui-core/src/style/palette_conversion.rs +82 -0
  69. package/vendor/ratatui-core/src/style/stylize.rs +668 -0
  70. package/vendor/ratatui-core/src/style.rs +1069 -0
  71. package/vendor/ratatui-core/src/symbols/bar.rs +51 -0
  72. package/vendor/ratatui-core/src/symbols/block.rs +51 -0
  73. package/vendor/ratatui-core/src/symbols/border.rs +709 -0
  74. package/vendor/ratatui-core/src/symbols/braille.rs +21 -0
  75. package/vendor/ratatui-core/src/symbols/half_block.rs +3 -0
  76. package/vendor/ratatui-core/src/symbols/line.rs +259 -0
  77. package/vendor/ratatui-core/src/symbols/marker.rs +82 -0
  78. package/vendor/ratatui-core/src/symbols/merge.rs +748 -0
  79. package/vendor/ratatui-core/src/symbols/pixel.rs +30 -0
  80. package/vendor/ratatui-core/src/symbols/scrollbar.rs +46 -0
  81. package/vendor/ratatui-core/src/symbols/shade.rs +5 -0
  82. package/vendor/ratatui-core/src/symbols.rs +15 -0
  83. package/vendor/ratatui-core/src/terminal/frame.rs +192 -0
  84. package/vendor/ratatui-core/src/terminal/terminal.rs +926 -0
  85. package/vendor/ratatui-core/src/terminal/viewport.rs +58 -0
  86. package/vendor/ratatui-core/src/terminal.rs +40 -0
  87. package/vendor/ratatui-core/src/text/grapheme.rs +84 -0
  88. package/vendor/ratatui-core/src/text/line.rs +1678 -0
  89. package/vendor/ratatui-core/src/text/masked.rs +149 -0
  90. package/vendor/ratatui-core/src/text/span.rs +904 -0
  91. package/vendor/ratatui-core/src/text/text.rs +1434 -0
  92. package/vendor/ratatui-core/src/text.rs +64 -0
  93. package/vendor/ratatui-core/src/widgets/stateful_widget.rs +193 -0
  94. package/vendor/ratatui-core/src/widgets/widget.rs +174 -0
  95. package/vendor/ratatui-core/src/widgets.rs +9 -0
  96. package/bin/gwt.js +0 -131
  97. package/scripts/postinstall.test.js +0 -71
  98. package/scripts/release-download.js +0 -66
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
+
2
3
  set -euo pipefail
3
4
 
4
5
  # Git設定(node:22-bookwormにはGitが含まれている)
@@ -8,49 +9,59 @@ git -C / config --global --add safe.directory /gwt
8
9
 
9
10
  # ユーザー名とメールの設定(環境変数から)
10
11
  if [ -n "${GITHUB_USERNAME:-}" ]; then
11
- git -C / config --global user.name "$GITHUB_USERNAME"
12
+ git -C / config --global user.name "$GITHUB_USERNAME"
12
13
  fi
13
14
 
14
15
  if [ -n "${GIT_USER_EMAIL:-}" ]; then
15
- git -C / config --global user.email "$GIT_USER_EMAIL"
16
+ git -C / config --global user.email "$GIT_USER_EMAIL"
16
17
  fi
17
18
 
18
19
  # Git認証ファイルを環境変数から作成
19
20
  if [ -n "${GITHUB_USERNAME:-}" ] && [ -n "${GITHUB_PERSONAL_ACCESS_TOKEN:-}" ]; then
20
- printf '%s\n' "https://${GITHUB_USERNAME}:${GITHUB_PERSONAL_ACCESS_TOKEN}@github.com" > /root/.git-credentials
21
- chmod 600 /root/.git-credentials
22
- git -C / config --global credential.helper store
21
+ printf '%s\n' "https://${GITHUB_USERNAME}:${GITHUB_PERSONAL_ACCESS_TOKEN}@github.com" > /root/.git-credentials
22
+ chmod 600 /root/.git-credentials
23
+ git -C / config --global credential.helper store
23
24
  fi
24
25
 
25
26
  # GitHub CLIの認証(GITHUB_TOKENが設定されている場合)
26
27
  if [ -n "${GITHUB_TOKEN:-}" ] && command -v gh &> /dev/null; then
27
- if echo "$GITHUB_TOKEN" | gh auth login --with-token; then
28
- echo "✅ GitHub CLI authenticated"
29
- else
30
- echo "⚠️ GitHub CLI authentication failed (non-fatal)" >&2
31
- fi
28
+ if echo "$GITHUB_TOKEN" | gh auth login --with-token; then
29
+ echo "✅ GitHub CLI authenticated"
30
+ else
31
+ echo "⚠️ GitHub CLI authentication failed (non-fatal)" >&2
32
+ fi
32
33
  fi
33
34
 
34
35
  # .codexディレクトリのセットアップ
35
36
  # auth.jsonをホストと同期(クロスプラットフォーム対応)
36
37
  mkdir -p /root/.codex
37
38
  if [ -f /root/.codex-host/auth.json ]; then
38
- # auth.jsonが誤ってディレクトリとして作成されている場合は削除
39
- if [ -d /root/.codex/auth.json ]; then
40
- echo "⚠️ Removing incorrectly created auth.json directory"
41
- rm -rf /root/.codex/auth.json
42
- fi
43
-
44
- # ホストのauth.jsonが存在しない、または空、またはホスト側が新しい場合はコピー
45
- if [ ! -f /root/.codex/auth.json ] || [ ! -s /root/.codex/auth.json ] || [ /root/.codex-host/auth.json -nt /root/.codex/auth.json ]; then
46
- cp /root/.codex-host/auth.json /root/.codex/auth.json
47
- chmod 600 /root/.codex/auth.json
48
- echo "✅ Codex auth.json synced from host"
49
- else
50
- echo "✅ Codex auth.json is up to date"
51
- fi
39
+ # auth.jsonが誤ってディレクトリとして作成されている場合は削除
40
+ if [ -d /root/.codex/auth.json ]; then
41
+ echo "⚠️ Removing incorrectly created auth.json directory"
42
+ rm -rf /root/.codex/auth.json
43
+ fi
44
+
45
+ # ホストのauth.jsonが存在しない、または空、またはホスト側が新しい場合はコピー
46
+ if [ ! -f /root/.codex/auth.json ] || [ ! -s /root/.codex/auth.json ] || [ /root/.codex-host/auth.json -nt /root/.codex/auth.json ]; then
47
+ cp /root/.codex-host/auth.json /root/.codex/auth.json
48
+ chmod 600 /root/.codex/auth.json
49
+ echo "✅ Codex auth.json synced from host"
50
+ else
51
+ echo "✅ Codex auth.json is up to date"
52
+ fi
53
+ else
54
+ echo "ℹ️ INFO: Codex auth.json not found on host (optional)"
55
+ fi
56
+
57
+ # .claudeディレクトリのセットアップ
58
+ # 認証・設定をホストと同期(クロスプラットフォーム対応)
59
+ mkdir -p /root/.claude
60
+ if [ -d /root/.claude-host ] && [ -n "$(find /root/.claude-host -mindepth 1 -maxdepth 1 2>/dev/null)" ]; then
61
+ cp -R /root/.claude-host/. /root/.claude/
62
+ echo "✅ Claude config synced from host"
52
63
  else
53
- echo "ℹ️ INFO: Codex auth.json not found on host (optional)"
64
+ echo "ℹ️ INFO: Claude config not found on host (optional)"
54
65
  fi
55
66
 
56
67
  echo "🚀 Docker development environment is ready!"
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ run_as_root() {
5
+ if [[ "$(id -u)" -eq 0 ]]; then
6
+ "$@"
7
+ elif command -v sudo >/dev/null 2>&1; then
8
+ sudo "$@"
9
+ else
10
+ echo "error: sudo is required when not running as root" >&2
11
+ exit 1
12
+ fi
13
+ }
14
+
15
+ install_args=(-y)
16
+ if [[ "${NO_INSTALL_RECOMMENDS:-0}" == "1" ]]; then
17
+ install_args+=(--no-install-recommends)
18
+ fi
19
+
20
+ if [[ "${SKIP_APT_UPDATE:-0}" != "1" ]]; then
21
+ run_as_root apt-get update
22
+ fi
23
+
24
+ appindicator_pkg=""
25
+ if apt-cache show libappindicator3-dev >/dev/null 2>&1; then
26
+ appindicator_pkg="libappindicator3-dev"
27
+ elif apt-cache show libayatana-appindicator3-dev >/dev/null 2>&1; then
28
+ appindicator_pkg="libayatana-appindicator3-dev"
29
+ else
30
+ echo "error: neither libappindicator3-dev nor libayatana-appindicator3-dev is available" >&2
31
+ exit 1
32
+ fi
33
+
34
+ packages=(
35
+ libwebkit2gtk-4.1-dev
36
+ "${appindicator_pkg}"
37
+ librsvg2-dev
38
+ patchelf
39
+ )
40
+
41
+ run_as_root apt-get install "${install_args[@]}" "${packages[@]}"
42
+
43
+ if [[ "${CLEAN_APT_CACHE:-0}" == "1" ]]; then
44
+ run_as_root apt-get clean
45
+ run_as_root rm -rf /var/lib/apt/lists/*
46
+ fi
@@ -1,261 +1,113 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * Postinstall script to download the appropriate gwt binary
4
- * for the current platform from GitHub Releases.
5
- */
6
-
7
- import {
8
- createWriteStream,
9
- existsSync,
10
- mkdirSync,
11
- chmodSync,
12
- unlinkSync,
13
- } from 'fs';
14
- import { dirname, join } from 'path';
15
- import { fileURLToPath, pathToFileURL } from 'url';
16
- import { get } from 'https';
17
- import {
18
- REPO,
19
- buildReleaseDownloadUrl,
20
- getPackageVersion,
21
- getPlatformArtifact,
22
- getSupportedPlatformKeys,
23
- } from './release-download.js';
24
-
25
- const __filename = fileURLToPath(import.meta.url);
26
- const __dirname = dirname(__filename);
2
+ "use strict";
27
3
 
28
- const BIN_DIR = join(__dirname, '..', 'bin');
29
- const BIN_NAME = process.platform === 'win32' ? 'gwt.exe' : 'gwt';
30
- const BIN_PATH = join(BIN_DIR, BIN_NAME);
4
+ const os = require("os");
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const https = require("https");
31
8
 
32
- const RETRY_CONFIG = {
33
- maxAttempts: 5,
34
- initialDelayMs: 500,
35
- backoffFactor: 2,
36
- maxDelayMs: 5000,
37
- };
9
+ const REPO = "akiojin/gwt";
10
+ const BIN_DIR = path.join(__dirname, "..", "bin");
11
+ const BINARY_NAME = os.platform() === "win32" ? "gwt-tui.exe" : "gwt-tui";
38
12
 
39
- const MAX_REDIRECTS = 5;
13
+ /**
14
+ * Detect the GitHub Release artifact name for the current platform/arch.
15
+ */
16
+ function artifactName() {
17
+ const platform = os.platform();
18
+ const arch = os.arch();
40
19
 
41
- function requirePlatformArtifact() {
42
- const artifact = getPlatformArtifact();
43
- if (!artifact) {
44
- console.error(`Unsupported platform: ${process.platform}-${process.arch}`);
45
- console.error(`Supported platforms: ${getSupportedPlatformKeys().join(', ')}`);
46
- process.exit(1);
20
+ if (platform === "darwin" && arch === "arm64") {
21
+ return "gwt-tui-macos-aarch64";
47
22
  }
48
- return artifact;
49
- }
50
-
51
- function getRetryDelayMs(attempt, config = RETRY_CONFIG) {
52
- const delay = config.initialDelayMs * Math.pow(config.backoffFactor, Math.max(0, attempt - 1));
53
- return Math.min(delay, config.maxDelayMs);
54
- }
55
-
56
- function isRetryableStatus(statusCode) {
57
- return statusCode === 403 || statusCode === 404 || statusCode >= 500;
58
- }
59
-
60
- function isRetryableError(error) {
61
- if (error && typeof error.statusCode === 'number') {
62
- return isRetryableStatus(error.statusCode);
23
+ if (platform === "darwin" && arch === "x64") {
24
+ return "gwt-tui-macos-x86_64";
25
+ }
26
+ if (platform === "linux" && arch === "x64") {
27
+ return "gwt-tui-linux-x86_64";
28
+ }
29
+ if (platform === "linux" && arch === "arm64") {
30
+ return "gwt-tui-linux-aarch64";
31
+ }
32
+ if (platform === "win32" && arch === "x64") {
33
+ return "gwt-tui-windows-x86_64";
63
34
  }
64
- return true;
65
- }
66
-
67
- function formatFailureGuidance(version, artifact) {
68
- const versionedUrl = version && version !== 'unknown'
69
- ? buildReleaseDownloadUrl(version, artifact)
70
- : null;
71
- return {
72
- versionedUrl,
73
- releasePageUrl: `https://github.com/${REPO}/releases`,
74
- buildCommand: 'cargo build --release',
75
- };
76
- }
77
-
78
- async function getReleaseAssetUrl(version, artifact, httpGet = get) {
79
- return new Promise((resolve) => {
80
- const options = {
81
- hostname: 'api.github.com',
82
- path: `/repos/${REPO}/releases/tags/v${version}`,
83
- headers: {
84
- 'User-Agent': 'gwt-postinstall',
85
- 'Accept': 'application/vnd.github.v3+json',
86
- },
87
- };
88
-
89
- const req = httpGet(options, (res) => {
90
- let data = '';
91
- res.on('data', (chunk) => data += chunk);
92
- res.on('end', () => {
93
- if (res.statusCode !== 200) {
94
- resolve(null);
95
- return;
96
- }
97
- try {
98
- const release = JSON.parse(data);
99
- const asset = release.assets?.find((entry) => entry.name === artifact);
100
- resolve(asset?.browser_download_url ?? null);
101
- } catch {
102
- resolve(null);
103
- }
104
- });
105
- });
106
35
 
107
- req.on('error', () => resolve(null));
108
- });
36
+ throw new Error(`Unsupported platform: ${platform}-${arch}`);
109
37
  }
110
38
 
111
- async function getDownloadUrl(version, artifact) {
112
- const assetUrl = await getReleaseAssetUrl(version, artifact);
113
- return assetUrl ?? buildReleaseDownloadUrl(version, artifact);
39
+ /**
40
+ * Read the target version from package.json.
41
+ */
42
+ function readVersion() {
43
+ const pkg = path.join(__dirname, "..", "package.json");
44
+ const data = JSON.parse(fs.readFileSync(pkg, "utf8"));
45
+ return data.version;
114
46
  }
115
47
 
116
- async function downloadFile(url, dest, httpGet = get) {
48
+ /**
49
+ * Follow redirects and download a URL to a local path.
50
+ */
51
+ function download(url, dest) {
117
52
  return new Promise((resolve, reject) => {
118
- const request = (currentUrl, redirectCount) => {
119
- const req = httpGet(currentUrl, (res) => {
120
- const statusCode = res.statusCode ?? 0;
121
-
122
- if ([301, 302, 303, 307, 308].includes(statusCode)) {
123
- const location = res.headers.location;
124
- res.resume();
125
- if (!location) {
126
- const error = new Error(`Redirect without location (HTTP ${statusCode})`);
127
- error.statusCode = statusCode;
128
- reject(error);
53
+ const file = fs.createWriteStream(dest);
54
+ const request = (u) => {
55
+ https
56
+ .get(u, { headers: { "User-Agent": "gwt-postinstall" } }, (res) => {
57
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
58
+ request(res.headers.location);
129
59
  return;
130
60
  }
131
- if (redirectCount >= MAX_REDIRECTS) {
132
- const error = new Error('Too many redirects');
133
- error.statusCode = statusCode;
134
- reject(error);
61
+ if (res.statusCode !== 200) {
62
+ file.close();
63
+ fs.unlink(dest, () => {});
64
+ reject(new Error(`Download failed: HTTP ${res.statusCode} for ${u}`));
135
65
  return;
136
66
  }
137
- const resolved = new URL(location, currentUrl).toString();
138
- request(resolved, redirectCount + 1);
139
- return;
140
- }
141
-
142
- if (statusCode !== 200) {
143
- res.resume();
144
- const error = new Error(`Failed to download: HTTP ${statusCode}`);
145
- error.statusCode = statusCode;
146
- reject(error);
147
- return;
148
- }
149
-
150
- const file = createWriteStream(dest);
151
- res.pipe(file);
152
-
153
- const cleanup = (err) => {
154
- file.close(() => {
155
- if (existsSync(dest)) unlinkSync(dest);
156
- reject(err);
67
+ res.pipe(file);
68
+ file.on("finish", () => {
69
+ file.close(resolve);
157
70
  });
158
- };
159
-
160
- file.on('finish', () => file.close(resolve));
161
- file.on('error', cleanup);
162
- res.on('error', cleanup);
163
- });
164
-
165
- req.on('error', (err) => {
166
- if (existsSync(dest)) unlinkSync(dest);
167
- reject(err);
168
- });
71
+ })
72
+ .on("error", (err) => {
73
+ file.close();
74
+ fs.unlink(dest, () => {});
75
+ reject(err);
76
+ });
169
77
  };
170
-
171
- request(url, 0);
78
+ request(url);
172
79
  });
173
80
  }
174
81
 
175
- async function downloadWithRetry(url, dest, config = RETRY_CONFIG) {
176
- let attempt = 0;
177
-
178
- while (attempt < config.maxAttempts) {
179
- attempt += 1;
180
- try {
181
- await downloadFile(url, dest);
182
- return;
183
- } catch (error) {
184
- if (!isRetryableError(error) || attempt >= config.maxAttempts) {
185
- throw error;
186
- }
187
- const delayMs = getRetryDelayMs(attempt, config);
188
- console.log(`Retrying download in ${delayMs}ms (attempt ${attempt}/${config.maxAttempts})...`);
189
- await new Promise((resolve) => setTimeout(resolve, delayMs));
190
- }
191
- }
192
- }
193
-
194
82
  async function main() {
195
- // Skip in CI environments where binary might be built differently
196
- if (process.env.CI || process.env.GITHUB_ACTIONS) {
197
- console.log('Skipping binary download in CI environment');
198
- return;
199
- }
200
-
201
- // Skip if binary already exists (e.g., local development)
202
- if (existsSync(BIN_PATH)) {
203
- console.log('Binary already exists, skipping download');
83
+ // Skip in CI or when running from source
84
+ if (process.env.CI) {
85
+ console.log("gwt: skipping binary download in CI");
204
86
  return;
205
87
  }
206
88
 
207
- const artifact = requirePlatformArtifact();
208
- let version = 'unknown';
209
- console.log(`Downloading gwt binary for ${process.platform}-${process.arch}...`);
210
-
211
- try {
212
- version = getPackageVersion();
213
- const url = await getDownloadUrl(version, artifact);
214
- console.log(`Downloading from: ${url}`);
89
+ const version = readVersion();
90
+ const artifact = artifactName();
91
+ const tag = `v${version}`;
92
+ const binaryUrl = `https://github.com/${REPO}/releases/download/${tag}/${artifact}/${BINARY_NAME}`;
215
93
 
216
- if (!existsSync(BIN_DIR)) {
217
- mkdirSync(BIN_DIR, { recursive: true });
218
- }
94
+ fs.mkdirSync(BIN_DIR, { recursive: true });
219
95
 
220
- await downloadWithRetry(url, BIN_PATH);
96
+ const dest = path.join(BIN_DIR, BINARY_NAME);
221
97
 
222
- // Make executable on Unix
223
- if (process.platform !== 'win32') {
224
- chmodSync(BIN_PATH, 0o755);
225
- }
98
+ console.log(`gwt: downloading ${tag} for ${os.platform()}-${os.arch()}...`);
226
99
 
227
- console.log('gwt binary installed successfully!');
228
- } catch (error) {
229
- const guidance = formatFailureGuidance(version, artifact);
230
- console.error('Failed to download gwt binary:', error.message);
231
- console.error('');
232
- console.error('You can manually download the binary from:');
233
- if (guidance.versionedUrl) {
234
- console.error(guidance.versionedUrl);
100
+ try {
101
+ await download(binaryUrl, dest);
102
+ if (os.platform() !== "win32") {
103
+ fs.chmodSync(dest, 0o755);
235
104
  }
236
- console.error(guidance.releasePageUrl);
237
- console.error('');
238
- console.error(`Or build from source with: ${guidance.buildCommand}`);
239
- process.exit(1);
105
+ console.log(`gwt: installed to ${dest}`);
106
+ } catch (err) {
107
+ console.error(`gwt: failed to download binary - ${err.message}`);
108
+ console.error("gwt: you can build from source with: cargo build --release -p gwt-tui");
109
+ process.exitCode = 0; // non-fatal so npm install does not fail
240
110
  }
241
111
  }
242
112
 
243
- const isDirectRun = process.argv[1]
244
- && pathToFileURL(process.argv[1]).href === import.meta.url;
245
-
246
- if (isDirectRun) {
247
- main();
248
- }
249
-
250
- export {
251
- RETRY_CONFIG,
252
- buildReleaseDownloadUrl,
253
- formatFailureGuidance,
254
- getRetryDelayMs,
255
- getReleaseAssetUrl,
256
- getDownloadUrl,
257
- getPackageVersion,
258
- getPlatformArtifact,
259
- isRetryableError,
260
- isRetryableStatus,
261
- };
113
+ main();