deepharness 0.0.2 → 0.0.3
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 +18 -38
- package/bin/dh.js +53 -21
- package/package.json +7 -4
- package/scripts/download-binary.js +139 -0
- package/scripts/postinstall.js +38 -12
package/README.md
CHANGED
|
@@ -4,74 +4,54 @@
|
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
7
|
-
`deepharness` npm
|
|
8
|
-
|
|
9
|
-
### 1. 先安装 `dh` 二进制文件(必须)
|
|
10
|
-
|
|
11
|
-
选择以下任一方式:
|
|
12
|
-
|
|
13
|
-
#### 方式 A:安装 DeepHarness Desktop
|
|
14
|
-
|
|
15
|
-
从发布页下载并安装桌面应用,它会自动将 `dh` 放入 PATH:
|
|
7
|
+
`deepharness` npm 包会在安装时自动下载对应平台的原生 `dh` 二进制文件。
|
|
16
8
|
|
|
17
9
|
```bash
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
#### 方式 B:从源码编译(需要 Rust 工具链)
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
git clone https://github.com/deepharness/deepharness-ent-desktop.git
|
|
25
|
-
cd deepharness-ent-desktop
|
|
26
|
-
cargo build --release -p deepharness-cli
|
|
27
|
-
|
|
28
|
-
# 安装到用户级可执行目录
|
|
29
|
-
mkdir -p ~/.local/bin
|
|
30
|
-
cp target/release/dh ~/.local/bin/dh
|
|
31
|
-
|
|
32
|
-
# 确保 ~/.local/bin 在 PATH 中
|
|
33
|
-
export PATH="$HOME/.local/bin:$PATH"
|
|
10
|
+
npm install -g deepharness
|
|
34
11
|
```
|
|
35
12
|
|
|
36
|
-
|
|
13
|
+
安装完成后验证:
|
|
37
14
|
|
|
38
15
|
```bash
|
|
39
|
-
|
|
40
|
-
npm install -g deepharness
|
|
16
|
+
dh --version
|
|
41
17
|
```
|
|
42
18
|
|
|
43
|
-
|
|
19
|
+
### 权限问题
|
|
44
20
|
|
|
45
|
-
|
|
21
|
+
如果 `npm install -g` 出现 `EACCES` 权限错误,推荐将 npm 全局目录改到用户主目录:
|
|
46
22
|
|
|
47
23
|
```bash
|
|
48
24
|
mkdir -p ~/.npm-global
|
|
49
25
|
npm config set prefix '~/.npm-global'
|
|
50
26
|
export PATH="$HOME/.npm-global/bin:$PATH"
|
|
51
|
-
#
|
|
27
|
+
# 将上面 export 加入 ~/.bashrc 或 ~/.zshrc
|
|
52
28
|
|
|
53
29
|
npm install -g deepharness
|
|
54
30
|
```
|
|
55
31
|
|
|
56
|
-
|
|
32
|
+
或者使用 `npx`(无需全局安装):
|
|
57
33
|
|
|
58
34
|
```bash
|
|
59
35
|
npx deepharness --version
|
|
60
36
|
```
|
|
61
37
|
|
|
62
|
-
###
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
dh --version
|
|
66
|
-
```
|
|
38
|
+
### 手动指定二进制路径
|
|
67
39
|
|
|
68
|
-
|
|
40
|
+
如果自动下载失败,或你想使用自己编译的 `dh`,可通过环境变量指定:
|
|
69
41
|
|
|
70
42
|
```bash
|
|
71
43
|
export DH_BINARY_PATH=/path/to/dh
|
|
72
44
|
dh --version
|
|
73
45
|
```
|
|
74
46
|
|
|
47
|
+
## 支持的平台
|
|
48
|
+
|
|
49
|
+
安装脚本会根据当前系统自动下载对应二进制:
|
|
50
|
+
|
|
51
|
+
- Linux x64 / arm64
|
|
52
|
+
- macOS x64 / arm64
|
|
53
|
+
- Windows x64
|
|
54
|
+
|
|
75
55
|
## 使用
|
|
76
56
|
|
|
77
57
|
```bash
|
package/bin/dh.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn, execSync } from 'child_process';
|
|
3
|
-
import { existsSync, realpathSync } from 'fs';
|
|
3
|
+
import { existsSync, realpathSync, readFileSync } from 'fs';
|
|
4
4
|
import { dirname, join, resolve } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { homedir } from 'os';
|
|
@@ -8,7 +8,7 @@ import { homedir } from 'os';
|
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
10
|
|
|
11
|
-
const SYSTEM_INSTALL_URL = 'https://github.com/
|
|
11
|
+
const SYSTEM_INSTALL_URL = 'https://github.com/WraithN/deepharness-ent-desktop';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Resolve the real path of the wrapper script, following symlinks created by
|
|
@@ -22,13 +22,13 @@ function resolveWrapperPath() {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
const WRAPPER_PATH = resolveWrapperPath();
|
|
26
|
+
|
|
25
27
|
/**
|
|
26
28
|
* Check whether a candidate path resolves to this wrapper script itself.
|
|
27
29
|
* This prevents `which dh` from returning the npm-installed JS wrapper and
|
|
28
30
|
* causing an infinite subprocess loop.
|
|
29
31
|
*/
|
|
30
|
-
const WRAPPER_PATH = resolveWrapperPath();
|
|
31
|
-
|
|
32
32
|
function isWrapperItself(candidate) {
|
|
33
33
|
try {
|
|
34
34
|
return realpathSync(candidate) === WRAPPER_PATH;
|
|
@@ -59,7 +59,7 @@ function findProjectRoot() {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* Build a list of candidate paths where the `dh`
|
|
62
|
+
* Build a list of candidate paths where the `dh` binary may live.
|
|
63
63
|
*/
|
|
64
64
|
function buildSearchPaths() {
|
|
65
65
|
const paths = [];
|
|
@@ -113,6 +113,16 @@ function findDhBinary() {
|
|
|
113
113
|
return null;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
function readPackageVersion() {
|
|
117
|
+
try {
|
|
118
|
+
const pkgPath = join(__dirname, '..', 'package.json');
|
|
119
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
120
|
+
return pkg.version;
|
|
121
|
+
} catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
116
126
|
function printInstallInstructions() {
|
|
117
127
|
console.error('Error: `dh` binary not found.');
|
|
118
128
|
console.error('');
|
|
@@ -131,22 +141,44 @@ function printInstallInstructions() {
|
|
|
131
141
|
console.error(' export DH_BINARY_PATH=/path/to/dh');
|
|
132
142
|
}
|
|
133
143
|
|
|
134
|
-
|
|
144
|
+
async function ensureDhBinary() {
|
|
145
|
+
const existing = findDhBinary();
|
|
146
|
+
if (existing) return existing;
|
|
147
|
+
|
|
148
|
+
// Try to download the binary from GitHub release on first use.
|
|
149
|
+
try {
|
|
150
|
+
const { downloadDhBinary } = await import('../scripts/download-binary.js');
|
|
151
|
+
const version = readPackageVersion();
|
|
152
|
+
if (!version) {
|
|
153
|
+
throw new Error('Cannot determine package version');
|
|
154
|
+
}
|
|
155
|
+
return await downloadDhBinary(version);
|
|
156
|
+
} catch (err) {
|
|
157
|
+
console.error(`[deepharness] Failed to download dh binary: ${err.message}`);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function main() {
|
|
163
|
+
const dhBin = await ensureDhBinary();
|
|
164
|
+
|
|
165
|
+
if (!dhBin) {
|
|
166
|
+
printInstallInstructions();
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
135
169
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
170
|
+
const args = process.argv.slice(2);
|
|
171
|
+
const proc = spawn(dhBin, args, {
|
|
172
|
+
stdio: 'inherit',
|
|
173
|
+
cwd: process.cwd(),
|
|
174
|
+
env: { ...process.env, DH_NPM_WRAPPER: '1' },
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
proc.on('exit', (code) => process.exit(code ?? 1));
|
|
178
|
+
proc.on('error', (err) => {
|
|
179
|
+
console.error(`Failed to start dh from ${dhBin}:`, err.message);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
});
|
|
139
182
|
}
|
|
140
183
|
|
|
141
|
-
|
|
142
|
-
const proc = spawn(dhBin, args, {
|
|
143
|
-
stdio: 'inherit',
|
|
144
|
-
cwd: process.cwd(),
|
|
145
|
-
env: { ...process.env, DH_NPM_WRAPPER: '1' },
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
proc.on('exit', (code) => process.exit(code ?? 1));
|
|
149
|
-
proc.on('error', (err) => {
|
|
150
|
-
console.error(`Failed to start dh from ${dhBin}:`, err.message);
|
|
151
|
-
process.exit(1);
|
|
152
|
-
});
|
|
184
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepharness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "DeepHarness CLI - Connect to AI coding agents with Claude Code, OpenCode, and more",
|
|
6
6
|
"bin": {
|
|
@@ -27,17 +27,20 @@
|
|
|
27
27
|
],
|
|
28
28
|
"author": "DeepHarness Team",
|
|
29
29
|
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"undici": "^6.0.0"
|
|
32
|
+
},
|
|
30
33
|
"engines": {
|
|
31
34
|
"node": ">= 18"
|
|
32
35
|
},
|
|
33
36
|
"repository": {
|
|
34
37
|
"type": "git",
|
|
35
|
-
"url": "git+https://github.com/
|
|
38
|
+
"url": "git+https://github.com/WraithN/deepharness-ent-desktop.git"
|
|
36
39
|
},
|
|
37
40
|
"bugs": {
|
|
38
|
-
"url": "https://github.com/
|
|
41
|
+
"url": "https://github.com/WraithN/deepharness-ent-desktop/issues"
|
|
39
42
|
},
|
|
40
|
-
"homepage": "https://github.com/
|
|
43
|
+
"homepage": "https://github.com/WraithN/deepharness-ent-desktop",
|
|
41
44
|
"publishConfig": {
|
|
42
45
|
"access": "public"
|
|
43
46
|
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Download the native `dh` binary from the GitHub release that matches the
|
|
4
|
+
* current platform and architecture.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, writeFileSync, chmodSync, readFileSync } from 'fs';
|
|
7
|
+
import { dirname, join } from 'path';
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const GITHUB_OWNER = 'WraithN';
|
|
12
|
+
const GITHUB_REPO = 'deepharness-ent-desktop';
|
|
13
|
+
const DOWNLOAD_TIMEOUT_MS = 60_000;
|
|
14
|
+
|
|
15
|
+
const PLATFORM_ASSET_NAMES = {
|
|
16
|
+
'linux:x64': 'dh-linux-x64',
|
|
17
|
+
'linux:arm64': 'dh-linux-arm64',
|
|
18
|
+
'darwin:x64': 'dh-darwin-x64',
|
|
19
|
+
'darwin:arm64': 'dh-darwin-arm64',
|
|
20
|
+
'win32:x64': 'dh-windows-x64.exe',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function getProxyUrl() {
|
|
24
|
+
return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function fetchWithProxy(url) {
|
|
28
|
+
const proxyUrl = getProxyUrl();
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
const timeoutId = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
if (proxyUrl) {
|
|
34
|
+
try {
|
|
35
|
+
const { ProxyAgent } = await import('undici');
|
|
36
|
+
return await fetch(url, {
|
|
37
|
+
signal: controller.signal,
|
|
38
|
+
dispatcher: new ProxyAgent(proxyUrl),
|
|
39
|
+
});
|
|
40
|
+
} catch (err) {
|
|
41
|
+
// If undici/ProxyAgent fails, fall back to default fetch so users
|
|
42
|
+
// without a problematic proxy still work.
|
|
43
|
+
console.warn(`[deepharness] Proxy download failed (${err.message}), retrying without proxy.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return await fetch(url, { signal: controller.signal });
|
|
48
|
+
} finally {
|
|
49
|
+
clearTimeout(timeoutId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getPackageVersion() {
|
|
54
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
55
|
+
const packageJsonPath = join(dirname(__filename), '..', 'package.json');
|
|
56
|
+
try {
|
|
57
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
58
|
+
return pkg.version;
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getAssetName() {
|
|
65
|
+
const key = `${process.platform}:${process.arch}`;
|
|
66
|
+
const assetName = PLATFORM_ASSET_NAMES[key];
|
|
67
|
+
if (!assetName) {
|
|
68
|
+
throw new Error(`Unsupported platform/architecture: ${key}. Supported platforms: ${Object.keys(PLATFORM_ASSET_NAMES).join(', ')}`);
|
|
69
|
+
}
|
|
70
|
+
return assetName;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getBinaryName() {
|
|
74
|
+
return process.platform === 'win32' ? 'dh.exe' : 'dh';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getInstallDir() {
|
|
78
|
+
return join(homedir(), '.local', 'bin');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getBinaryPath() {
|
|
82
|
+
return join(getInstallDir(), getBinaryName());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getDownloadUrl(version, assetName) {
|
|
86
|
+
return `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/releases/download/dh-v${version}/${assetName}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Download the binary for the current platform and install it to ~/.local/bin.
|
|
91
|
+
* Returns the path to the installed binary.
|
|
92
|
+
*/
|
|
93
|
+
export async function downloadDhBinary(version) {
|
|
94
|
+
const assetName = getAssetName();
|
|
95
|
+
const binaryPath = getBinaryPath();
|
|
96
|
+
const downloadUrl = getDownloadUrl(version, assetName);
|
|
97
|
+
|
|
98
|
+
console.log(`[deepharness] Downloading dh ${version} for ${process.platform}-${process.arch}...`);
|
|
99
|
+
console.log(`[deepharness] URL: ${downloadUrl}`);
|
|
100
|
+
|
|
101
|
+
const response = await fetchWithProxy(downloadUrl);
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
throw new Error(`Download failed: ${response.status} ${response.statusText} (${downloadUrl})`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
107
|
+
|
|
108
|
+
mkdirSync(getInstallDir(), { recursive: true });
|
|
109
|
+
writeFileSync(binaryPath, buffer);
|
|
110
|
+
|
|
111
|
+
if (process.platform !== 'win32') {
|
|
112
|
+
chmodSync(binaryPath, 0o755);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log(`[deepharness] Installed dh to ${binaryPath}`);
|
|
116
|
+
return binaryPath;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Check whether the installed binary is present.
|
|
121
|
+
*/
|
|
122
|
+
export function isBinaryInstalled() {
|
|
123
|
+
return existsSync(getBinaryPath());
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { getBinaryPath, getPackageVersion };
|
|
127
|
+
|
|
128
|
+
// CLI entry point for testing or manual download.
|
|
129
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
130
|
+
const version = process.argv[2] || getPackageVersion();
|
|
131
|
+
if (!version) {
|
|
132
|
+
console.error('Usage: node download-binary.js <version>');
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
downloadDhBinary(version).catch((err) => {
|
|
136
|
+
console.error(err.message);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
});
|
|
139
|
+
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The npm package is only a wrapper; it needs the native `dh` binary to be
|
|
6
6
|
* present on the system. This script verifies that the binary exists and,
|
|
7
|
-
* when
|
|
8
|
-
*
|
|
7
|
+
* when possible, installs it automatically by downloading from the matching
|
|
8
|
+
* GitHub release or by building from source.
|
|
9
9
|
*/
|
|
10
|
-
import { existsSync, realpathSync } from 'fs';
|
|
10
|
+
import { existsSync, realpathSync, readFileSync } from 'fs';
|
|
11
11
|
import { dirname, join } from 'path';
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
13
13
|
import { homedir } from 'os';
|
|
@@ -16,7 +16,7 @@ import { execSync } from 'child_process';
|
|
|
16
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
17
|
const __dirname = dirname(__filename);
|
|
18
18
|
|
|
19
|
-
const SYSTEM_INSTALL_URL = 'https://github.com/
|
|
19
|
+
const SYSTEM_INSTALL_URL = 'https://github.com/WraithN/deepharness-ent-desktop';
|
|
20
20
|
|
|
21
21
|
function resolveWrapperPath() {
|
|
22
22
|
try {
|
|
@@ -72,8 +72,14 @@ function findExistingDhBinary() {
|
|
|
72
72
|
return null;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function
|
|
76
|
-
|
|
75
|
+
function readPackageVersion() {
|
|
76
|
+
try {
|
|
77
|
+
const pkgPath = join(__dirname, '..', 'package.json');
|
|
78
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
79
|
+
return pkg.version;
|
|
80
|
+
} catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
function buildFromSource(projectRoot) {
|
|
@@ -84,22 +90,32 @@ function buildFromSource(projectRoot) {
|
|
|
84
90
|
stdio: 'inherit',
|
|
85
91
|
});
|
|
86
92
|
return true;
|
|
87
|
-
} catch
|
|
93
|
+
} catch {
|
|
88
94
|
console.error('[deepharness] Failed to build dh from source.');
|
|
89
95
|
return false;
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
function
|
|
99
|
+
async function downloadBinary() {
|
|
100
|
+
const { downloadDhBinary } = await import('./download-binary.js');
|
|
101
|
+
const version = readPackageVersion();
|
|
102
|
+
if (!version) {
|
|
103
|
+
throw new Error('Cannot determine package version');
|
|
104
|
+
}
|
|
105
|
+
return downloadDhBinary(version);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function main() {
|
|
94
109
|
// If a usable binary already exists, nothing more to do.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
console.log(`[deepharness] Found dh binary at ${
|
|
110
|
+
const existing = findExistingDhBinary();
|
|
111
|
+
if (existing) {
|
|
112
|
+
console.log(`[deepharness] Found dh binary at ${existing}`);
|
|
98
113
|
return;
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
const projectRoot = findProjectRoot();
|
|
102
117
|
|
|
118
|
+
// Prefer building from source when installed inside the repository.
|
|
103
119
|
if (projectRoot) {
|
|
104
120
|
console.log('[deepharness] dh binary not found; attempting to build from source...');
|
|
105
121
|
const built = buildFromSource(projectRoot);
|
|
@@ -114,10 +130,20 @@ function main() {
|
|
|
114
130
|
}
|
|
115
131
|
}
|
|
116
132
|
|
|
133
|
+
// Otherwise try to download the matching release binary.
|
|
134
|
+
try {
|
|
135
|
+
await downloadBinary();
|
|
136
|
+
return;
|
|
137
|
+
} catch (err) {
|
|
138
|
+
console.warn(`[deepharness] Could not download binary: ${err.message}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
117
141
|
console.warn('[deepharness] The native `dh` binary is not installed.');
|
|
118
142
|
console.warn('[deepharness] The `dh` command will not work until it is available.');
|
|
119
143
|
console.warn(`[deepharness] Install DeepHarness Desktop from: ${SYSTEM_INSTALL_URL}`);
|
|
120
144
|
console.warn('[deepharness] Or build from source: cargo build --release -p deepharness-cli');
|
|
121
145
|
}
|
|
122
146
|
|
|
123
|
-
main()
|
|
147
|
+
main().catch((err) => {
|
|
148
|
+
console.warn(`[deepharness] Post-install hook failed: ${err.message}`);
|
|
149
|
+
});
|