ancoder-skill-cli 0.13.38-beta.14 → 0.13.38-beta.18
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 +467 -467
- package/bin/skill-cli.js +52 -52
- package/bin/targets/skill-cli-darwin-arm64 +0 -0
- package/bin/targets/skill-cli-darwin-x64 +0 -0
- package/bin/targets/skill-cli-linux-arm64 +0 -0
- package/bin/targets/skill-cli-linux-x64 +0 -0
- package/bin/targets/skill-cli-win32-x64.exe +0 -0
- package/package.json +54 -54
- package/scripts/check-bin.js +176 -176
- package/scripts/install.ps1 +150 -150
- package/scripts/make-install-bundle.js +180 -180
- package/scripts/postinstall.js +36 -36
package/scripts/install.ps1
CHANGED
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
param(
|
|
2
|
-
[string]$BaseUrl = $env:SKILL_CLI_BASE_URL,
|
|
3
|
-
[string]$Version = $env:SKILL_CLI_VERSION,
|
|
4
|
-
[string]$InstallDir = $env:SKILL_CLI_INSTALL_DIR,
|
|
5
|
-
[string]$ClaudeDir = $env:SKILL_CLI_CLAUDE_DIR,
|
|
6
|
-
[ValidateSet("lite", "full", "none")]
|
|
7
|
-
[string]$Doctor = $(if ($env:SKILL_CLI_DOCTOR) { $env:SKILL_CLI_DOCTOR } else { "lite" }),
|
|
8
|
-
[switch]$NoInstall,
|
|
9
|
-
[switch]$NoPathUpdate,
|
|
10
|
-
[switch]$DryRun
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
$ErrorActionPreference = "Stop"
|
|
14
|
-
|
|
15
|
-
function Test-TruthyEnv {
|
|
16
|
-
param([string]$Value)
|
|
17
|
-
if (-not $Value) {
|
|
18
|
-
return $false
|
|
19
|
-
}
|
|
20
|
-
return @("1", "true", "yes", "on") -contains $Value.ToLowerInvariant()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (Test-TruthyEnv $env:SKILL_CLI_NO_INSTALL) {
|
|
24
|
-
$NoInstall = $true
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (Test-TruthyEnv $env:SKILL_CLI_NO_PATH_UPDATE) {
|
|
28
|
-
$NoPathUpdate = $true
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (Test-TruthyEnv $env:SKILL_CLI_DRY_RUN) {
|
|
32
|
-
$DryRun = $true
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
$baseUrlWasProvided = [bool]$BaseUrl
|
|
36
|
-
|
|
37
|
-
if (-not $Version) {
|
|
38
|
-
$Version = "main"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (-not $BaseUrl) {
|
|
42
|
-
$BaseUrl = "https://gitee.com/marvin-dev/skill-cli-release/raw/$Version/bin/targets"
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (-not $InstallDir) {
|
|
46
|
-
$InstallDir = Join-Path $env:LOCALAPPDATA "Programs\skill-cli"
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (-not [Environment]::Is64BitOperatingSystem) {
|
|
50
|
-
throw "skill-cli currently provides a Windows x64 binary only."
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
$asset = "skill-cli-win32-x64.exe"
|
|
54
|
-
$url = ($BaseUrl.TrimEnd("/")) + "/" + $asset
|
|
55
|
-
$target = Join-Path $InstallDir "skill-cli.exe"
|
|
56
|
-
|
|
57
|
-
Write-Host "skill-cli installer"
|
|
58
|
-
Write-Host " asset: $asset"
|
|
59
|
-
Write-Host " source: $url"
|
|
60
|
-
Write-Host " target: $target"
|
|
61
|
-
if (-not $baseUrlWasProvided) {
|
|
62
|
-
Write-Host " version: $Version"
|
|
63
|
-
}
|
|
64
|
-
if ($ClaudeDir) {
|
|
65
|
-
Write-Host " claude dir: $ClaudeDir"
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if ($DryRun) {
|
|
69
|
-
Write-Host "dry run: no files written"
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
$tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("skill-cli-install-" + [Guid]::NewGuid().ToString("N"))
|
|
74
|
-
New-Item -ItemType Directory -Path $tmp -Force | Out-Null
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
$downloaded = Join-Path $tmp $asset
|
|
78
|
-
$downloadedOk = $false
|
|
79
|
-
for ($attempt = 1; $attempt -le 3; $attempt++) {
|
|
80
|
-
try {
|
|
81
|
-
Invoke-WebRequest -Uri $url -OutFile $downloaded -UseBasicParsing
|
|
82
|
-
$downloadedOk = $true
|
|
83
|
-
break
|
|
84
|
-
} catch {
|
|
85
|
-
if ($attempt -eq 3) {
|
|
86
|
-
throw
|
|
87
|
-
}
|
|
88
|
-
Start-Sleep -Seconds (2 * $attempt)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (-not $downloadedOk) {
|
|
92
|
-
throw "download failed: $url"
|
|
93
|
-
}
|
|
94
|
-
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
|
95
|
-
Copy-Item -LiteralPath $downloaded -Destination $target -Force
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
Unblock-File -LiteralPath $target
|
|
99
|
-
} catch {
|
|
100
|
-
# Unblock-File can fail on filesystems without Zone.Identifier streams.
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (-not $NoPathUpdate) {
|
|
104
|
-
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
105
|
-
$parts = @()
|
|
106
|
-
if ($userPath) {
|
|
107
|
-
$parts = $userPath -split ';' | Where-Object { $_ }
|
|
108
|
-
}
|
|
109
|
-
$alreadyInPath = $false
|
|
110
|
-
foreach ($part in $parts) {
|
|
111
|
-
if ([string]::Equals($part.TrimEnd('\'), $InstallDir.TrimEnd('\'), [StringComparison]::OrdinalIgnoreCase)) {
|
|
112
|
-
$alreadyInPath = $true
|
|
113
|
-
break
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (-not $alreadyInPath) {
|
|
117
|
-
$newPath = if ($userPath) { "$userPath;$InstallDir" } else { $InstallDir }
|
|
118
|
-
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
|
|
119
|
-
$env:Path = "$env:Path;$InstallDir"
|
|
120
|
-
Write-Host " PATH: added to current user PATH"
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
Write-Host ""
|
|
125
|
-
& $target version
|
|
126
|
-
|
|
127
|
-
$claudeArgs = @()
|
|
128
|
-
if ($ClaudeDir) {
|
|
129
|
-
$claudeArgs += @("--claude-dir", $ClaudeDir)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (-not $NoInstall) {
|
|
133
|
-
Write-Host ""
|
|
134
|
-
& $target install @claudeArgs
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if ($Doctor -eq "lite") {
|
|
138
|
-
Write-Host ""
|
|
139
|
-
& $target doctor @claudeArgs --check-adversarial=false
|
|
140
|
-
} elseif ($Doctor -eq "full") {
|
|
141
|
-
Write-Host ""
|
|
142
|
-
& $target doctor @claudeArgs
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
Write-Host ""
|
|
146
|
-
Write-Host "skill-cli install complete."
|
|
147
|
-
Write-Host "Open a new terminal and run: skill-cli doctor"
|
|
148
|
-
} finally {
|
|
149
|
-
Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue
|
|
150
|
-
}
|
|
1
|
+
param(
|
|
2
|
+
[string]$BaseUrl = $env:SKILL_CLI_BASE_URL,
|
|
3
|
+
[string]$Version = $env:SKILL_CLI_VERSION,
|
|
4
|
+
[string]$InstallDir = $env:SKILL_CLI_INSTALL_DIR,
|
|
5
|
+
[string]$ClaudeDir = $env:SKILL_CLI_CLAUDE_DIR,
|
|
6
|
+
[ValidateSet("lite", "full", "none")]
|
|
7
|
+
[string]$Doctor = $(if ($env:SKILL_CLI_DOCTOR) { $env:SKILL_CLI_DOCTOR } else { "lite" }),
|
|
8
|
+
[switch]$NoInstall,
|
|
9
|
+
[switch]$NoPathUpdate,
|
|
10
|
+
[switch]$DryRun
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
$ErrorActionPreference = "Stop"
|
|
14
|
+
|
|
15
|
+
function Test-TruthyEnv {
|
|
16
|
+
param([string]$Value)
|
|
17
|
+
if (-not $Value) {
|
|
18
|
+
return $false
|
|
19
|
+
}
|
|
20
|
+
return @("1", "true", "yes", "on") -contains $Value.ToLowerInvariant()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (Test-TruthyEnv $env:SKILL_CLI_NO_INSTALL) {
|
|
24
|
+
$NoInstall = $true
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (Test-TruthyEnv $env:SKILL_CLI_NO_PATH_UPDATE) {
|
|
28
|
+
$NoPathUpdate = $true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (Test-TruthyEnv $env:SKILL_CLI_DRY_RUN) {
|
|
32
|
+
$DryRun = $true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$baseUrlWasProvided = [bool]$BaseUrl
|
|
36
|
+
|
|
37
|
+
if (-not $Version) {
|
|
38
|
+
$Version = "main"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (-not $BaseUrl) {
|
|
42
|
+
$BaseUrl = "https://gitee.com/marvin-dev/skill-cli-release/raw/$Version/bin/targets"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (-not $InstallDir) {
|
|
46
|
+
$InstallDir = Join-Path $env:LOCALAPPDATA "Programs\skill-cli"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (-not [Environment]::Is64BitOperatingSystem) {
|
|
50
|
+
throw "skill-cli currently provides a Windows x64 binary only."
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
$asset = "skill-cli-win32-x64.exe"
|
|
54
|
+
$url = ($BaseUrl.TrimEnd("/")) + "/" + $asset
|
|
55
|
+
$target = Join-Path $InstallDir "skill-cli.exe"
|
|
56
|
+
|
|
57
|
+
Write-Host "skill-cli installer"
|
|
58
|
+
Write-Host " asset: $asset"
|
|
59
|
+
Write-Host " source: $url"
|
|
60
|
+
Write-Host " target: $target"
|
|
61
|
+
if (-not $baseUrlWasProvided) {
|
|
62
|
+
Write-Host " version: $Version"
|
|
63
|
+
}
|
|
64
|
+
if ($ClaudeDir) {
|
|
65
|
+
Write-Host " claude dir: $ClaudeDir"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if ($DryRun) {
|
|
69
|
+
Write-Host "dry run: no files written"
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
$tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("skill-cli-install-" + [Guid]::NewGuid().ToString("N"))
|
|
74
|
+
New-Item -ItemType Directory -Path $tmp -Force | Out-Null
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
$downloaded = Join-Path $tmp $asset
|
|
78
|
+
$downloadedOk = $false
|
|
79
|
+
for ($attempt = 1; $attempt -le 3; $attempt++) {
|
|
80
|
+
try {
|
|
81
|
+
Invoke-WebRequest -Uri $url -OutFile $downloaded -UseBasicParsing
|
|
82
|
+
$downloadedOk = $true
|
|
83
|
+
break
|
|
84
|
+
} catch {
|
|
85
|
+
if ($attempt -eq 3) {
|
|
86
|
+
throw
|
|
87
|
+
}
|
|
88
|
+
Start-Sleep -Seconds (2 * $attempt)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (-not $downloadedOk) {
|
|
92
|
+
throw "download failed: $url"
|
|
93
|
+
}
|
|
94
|
+
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
|
95
|
+
Copy-Item -LiteralPath $downloaded -Destination $target -Force
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
Unblock-File -LiteralPath $target
|
|
99
|
+
} catch {
|
|
100
|
+
# Unblock-File can fail on filesystems without Zone.Identifier streams.
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (-not $NoPathUpdate) {
|
|
104
|
+
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
105
|
+
$parts = @()
|
|
106
|
+
if ($userPath) {
|
|
107
|
+
$parts = $userPath -split ';' | Where-Object { $_ }
|
|
108
|
+
}
|
|
109
|
+
$alreadyInPath = $false
|
|
110
|
+
foreach ($part in $parts) {
|
|
111
|
+
if ([string]::Equals($part.TrimEnd('\'), $InstallDir.TrimEnd('\'), [StringComparison]::OrdinalIgnoreCase)) {
|
|
112
|
+
$alreadyInPath = $true
|
|
113
|
+
break
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (-not $alreadyInPath) {
|
|
117
|
+
$newPath = if ($userPath) { "$userPath;$InstallDir" } else { $InstallDir }
|
|
118
|
+
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
|
|
119
|
+
$env:Path = "$env:Path;$InstallDir"
|
|
120
|
+
Write-Host " PATH: added to current user PATH"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Write-Host ""
|
|
125
|
+
& $target version
|
|
126
|
+
|
|
127
|
+
$claudeArgs = @()
|
|
128
|
+
if ($ClaudeDir) {
|
|
129
|
+
$claudeArgs += @("--claude-dir", $ClaudeDir)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (-not $NoInstall) {
|
|
133
|
+
Write-Host ""
|
|
134
|
+
& $target install @claudeArgs
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ($Doctor -eq "lite") {
|
|
138
|
+
Write-Host ""
|
|
139
|
+
& $target doctor @claudeArgs --check-adversarial=false
|
|
140
|
+
} elseif ($Doctor -eq "full") {
|
|
141
|
+
Write-Host ""
|
|
142
|
+
& $target doctor @claudeArgs
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
Write-Host ""
|
|
146
|
+
Write-Host "skill-cli install complete."
|
|
147
|
+
Write-Host "Open a new terminal and run: skill-cli doctor"
|
|
148
|
+
} finally {
|
|
149
|
+
Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue
|
|
150
|
+
}
|
|
@@ -1,180 +1,180 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
const rootDir = path.join(__dirname, '..');
|
|
8
|
-
const outDir = path.join(rootDir, 'dist', 'install');
|
|
9
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
|
|
10
|
-
const version = `v${pkg.version}`;
|
|
11
|
-
const generatedAt = normalizeGeneratedAt(process.env.SKILL_CLI_BUNDLE_GENERATED_AT);
|
|
12
|
-
const targets = [
|
|
13
|
-
'skill-cli-darwin-arm64',
|
|
14
|
-
'skill-cli-darwin-x64',
|
|
15
|
-
'skill-cli-linux-arm64',
|
|
16
|
-
'skill-cli-linux-x64',
|
|
17
|
-
'skill-cli-win32-x64.exe',
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
const args = process.argv.slice(2);
|
|
21
|
-
let baseURL = '';
|
|
22
|
-
let rootURL = '';
|
|
23
|
-
let scriptRootURL = '';
|
|
24
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
25
|
-
if (args[i] === '--base-url') {
|
|
26
|
-
baseURL = args[i + 1] || '';
|
|
27
|
-
i += 1;
|
|
28
|
-
} else if (args[i] === '--root') {
|
|
29
|
-
rootURL = args[i + 1] || '';
|
|
30
|
-
i += 1;
|
|
31
|
-
} else if (args[i] === '--script-root') {
|
|
32
|
-
scriptRootURL = args[i + 1] || '';
|
|
33
|
-
i += 1;
|
|
34
|
-
} else if (args[i] === '-h' || args[i] === '--help') {
|
|
35
|
-
console.log(`Usage:
|
|
36
|
-
node scripts/make-install-bundle.js [--root URL]
|
|
37
|
-
node scripts/make-install-bundle.js [--base-url URL]
|
|
38
|
-
node scripts/make-install-bundle.js [--base-url URL] [--script-root URL]
|
|
39
|
-
|
|
40
|
-
Creates dist/install/ with one-line installer scripts and prebuilt binaries.
|
|
41
|
-
When --root is provided, generated installer copies default to ROOT/bin/targets.
|
|
42
|
-
When --base-url is provided, generated installer copies default to that URL
|
|
43
|
-
for binary downloads, which is useful for intranet static hosting.
|
|
44
|
-
When --script-root is provided, README examples point to SCRIPT_ROOT/scripts.`);
|
|
45
|
-
process.exit(0);
|
|
46
|
-
} else {
|
|
47
|
-
console.error(`unknown option: ${args[i]}`);
|
|
48
|
-
process.exit(2);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function trimSlash(value) {
|
|
53
|
-
return value.replace(/\/+$/, '');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (rootURL && baseURL) {
|
|
57
|
-
console.error('use either --root or --base-url, not both');
|
|
58
|
-
process.exit(2);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (rootURL) {
|
|
62
|
-
rootURL = trimSlash(rootURL);
|
|
63
|
-
baseURL = `${rootURL}/bin/targets`;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (scriptRootURL) {
|
|
67
|
-
scriptRootURL = trimSlash(scriptRootURL);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function copyFile(src, dest) {
|
|
71
|
-
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
72
|
-
fs.copyFileSync(src, dest);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function writeFile(dest, content) {
|
|
76
|
-
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
77
|
-
fs.writeFileSync(dest, content);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function normalizeGeneratedAt(value) {
|
|
81
|
-
if (!value) {
|
|
82
|
-
return new Date().toISOString();
|
|
83
|
-
}
|
|
84
|
-
const parsed = new Date(value);
|
|
85
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
86
|
-
console.error(`invalid SKILL_CLI_BUNDLE_GENERATED_AT: ${value}`);
|
|
87
|
-
process.exit(2);
|
|
88
|
-
}
|
|
89
|
-
return parsed.toISOString();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
fs.rmSync(outDir, { recursive: true, force: true });
|
|
93
|
-
|
|
94
|
-
for (const target of targets) {
|
|
95
|
-
const src = path.join(rootDir, 'bin', 'targets', target);
|
|
96
|
-
if (!fs.existsSync(src)) {
|
|
97
|
-
console.error(`missing binary: ${src}`);
|
|
98
|
-
process.exit(1);
|
|
99
|
-
}
|
|
100
|
-
copyFile(src, path.join(outDir, 'bin', 'targets', target));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let installSH = fs.readFileSync(path.join(rootDir, 'scripts', 'install.sh'), 'utf8');
|
|
104
|
-
let installPS1 = fs.readFileSync(path.join(rootDir, 'scripts', 'install.ps1'), 'utf8');
|
|
105
|
-
|
|
106
|
-
installSH = installSH.replace(/DEFAULT_VERSION="[^"]+"/, `DEFAULT_VERSION="${version}"`);
|
|
107
|
-
installSH = installSH.replace(
|
|
108
|
-
/SKILL_CLI_VERSION Same as --version\. Default: [^\n]+/,
|
|
109
|
-
`SKILL_CLI_VERSION Same as --version. Default: ${version}.`
|
|
110
|
-
);
|
|
111
|
-
installPS1 = installPS1.replace(/\$Version = "[^"]+"/, `$Version = "${version}"`);
|
|
112
|
-
|
|
113
|
-
if (baseURL) {
|
|
114
|
-
const normalizedBaseURL = trimSlash(baseURL);
|
|
115
|
-
installSH = installSH.replace(
|
|
116
|
-
/DEFAULT_BASE_URL="https:\/\/gitee\.com\/marvin-dev\/skill-cli-release\/raw\/\$\{VERSION\}\/bin\/targets"/,
|
|
117
|
-
`DEFAULT_BASE_URL="${normalizedBaseURL}"`
|
|
118
|
-
).replace(
|
|
119
|
-
/DEFAULT_BASE_URL_USES_VERSION=1/,
|
|
120
|
-
'DEFAULT_BASE_URL_USES_VERSION=0'
|
|
121
|
-
);
|
|
122
|
-
installPS1 = installPS1.replace(
|
|
123
|
-
/\$BaseUrl = "https:\/\/gitee\.com\/marvin-dev\/skill-cli-release\/raw\/\$Version\/bin\/targets"/,
|
|
124
|
-
`$BaseUrl = "${normalizedBaseURL}"`
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
writeFile(path.join(outDir, 'scripts', 'install.sh'), installSH);
|
|
129
|
-
writeFile(path.join(outDir, 'scripts', 'install.ps1'), installPS1);
|
|
130
|
-
|
|
131
|
-
const manifest = {
|
|
132
|
-
package: pkg.name,
|
|
133
|
-
version: pkg.version,
|
|
134
|
-
tag: version,
|
|
135
|
-
generatedAt,
|
|
136
|
-
rootURL: rootURL || null,
|
|
137
|
-
scriptRootURL: scriptRootURL || null,
|
|
138
|
-
baseURL: baseURL || null,
|
|
139
|
-
files: [
|
|
140
|
-
'scripts/install.ps1',
|
|
141
|
-
'scripts/install.sh',
|
|
142
|
-
...targets.map((target) => `bin/targets/${target}`),
|
|
143
|
-
],
|
|
144
|
-
};
|
|
145
|
-
writeFile(path.join(outDir, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
146
|
-
|
|
147
|
-
function inferInstallRootFromBaseURL(value) {
|
|
148
|
-
const normalized = trimSlash(value);
|
|
149
|
-
if (normalized.endsWith('/bin/targets')) {
|
|
150
|
-
return normalized.slice(0, -'/bin/targets'.length);
|
|
151
|
-
}
|
|
152
|
-
return '<your-hosted-root>';
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const installRoot = scriptRootURL || rootURL || (baseURL ? inferInstallRootFromBaseURL(baseURL) : `https://gitee.com/marvin-dev/skill-cli-release/raw/${version}`);
|
|
156
|
-
const psURL = baseURL ? `${installRoot}/scripts/install.ps1` : `${installRoot}/scripts/install.ps1`;
|
|
157
|
-
const shURL = baseURL ? `${installRoot}/scripts/install.sh` : `${installRoot}/scripts/install.sh`;
|
|
158
|
-
|
|
159
|
-
writeFile(path.join(outDir, 'README.txt'), `skill-cli ${version} install bundle
|
|
160
|
-
|
|
161
|
-
Host this directory as a static tree. Required layout:
|
|
162
|
-
scripts/install.ps1
|
|
163
|
-
scripts/install.sh
|
|
164
|
-
bin/targets/skill-cli-*
|
|
165
|
-
|
|
166
|
-
Windows PowerShell:
|
|
167
|
-
irm ${psURL} | iex
|
|
168
|
-
|
|
169
|
-
macOS/Linux:
|
|
170
|
-
curl -fsSL ${shURL} | bash
|
|
171
|
-
|
|
172
|
-
If --base-url was not used to generate this bundle, set SKILL_CLI_BASE_URL
|
|
173
|
-
to the hosted bin/targets URL before running the installer.
|
|
174
|
-
`);
|
|
175
|
-
|
|
176
|
-
console.log(`Created ${outDir}`);
|
|
177
|
-
console.log(`Version: ${version}`);
|
|
178
|
-
if (baseURL) {
|
|
179
|
-
console.log(`Default binary base URL: ${baseURL}`);
|
|
180
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const rootDir = path.join(__dirname, '..');
|
|
8
|
+
const outDir = path.join(rootDir, 'dist', 'install');
|
|
9
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
|
|
10
|
+
const version = `v${pkg.version}`;
|
|
11
|
+
const generatedAt = normalizeGeneratedAt(process.env.SKILL_CLI_BUNDLE_GENERATED_AT);
|
|
12
|
+
const targets = [
|
|
13
|
+
'skill-cli-darwin-arm64',
|
|
14
|
+
'skill-cli-darwin-x64',
|
|
15
|
+
'skill-cli-linux-arm64',
|
|
16
|
+
'skill-cli-linux-x64',
|
|
17
|
+
'skill-cli-win32-x64.exe',
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const args = process.argv.slice(2);
|
|
21
|
+
let baseURL = '';
|
|
22
|
+
let rootURL = '';
|
|
23
|
+
let scriptRootURL = '';
|
|
24
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
25
|
+
if (args[i] === '--base-url') {
|
|
26
|
+
baseURL = args[i + 1] || '';
|
|
27
|
+
i += 1;
|
|
28
|
+
} else if (args[i] === '--root') {
|
|
29
|
+
rootURL = args[i + 1] || '';
|
|
30
|
+
i += 1;
|
|
31
|
+
} else if (args[i] === '--script-root') {
|
|
32
|
+
scriptRootURL = args[i + 1] || '';
|
|
33
|
+
i += 1;
|
|
34
|
+
} else if (args[i] === '-h' || args[i] === '--help') {
|
|
35
|
+
console.log(`Usage:
|
|
36
|
+
node scripts/make-install-bundle.js [--root URL]
|
|
37
|
+
node scripts/make-install-bundle.js [--base-url URL]
|
|
38
|
+
node scripts/make-install-bundle.js [--base-url URL] [--script-root URL]
|
|
39
|
+
|
|
40
|
+
Creates dist/install/ with one-line installer scripts and prebuilt binaries.
|
|
41
|
+
When --root is provided, generated installer copies default to ROOT/bin/targets.
|
|
42
|
+
When --base-url is provided, generated installer copies default to that URL
|
|
43
|
+
for binary downloads, which is useful for intranet static hosting.
|
|
44
|
+
When --script-root is provided, README examples point to SCRIPT_ROOT/scripts.`);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
} else {
|
|
47
|
+
console.error(`unknown option: ${args[i]}`);
|
|
48
|
+
process.exit(2);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function trimSlash(value) {
|
|
53
|
+
return value.replace(/\/+$/, '');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (rootURL && baseURL) {
|
|
57
|
+
console.error('use either --root or --base-url, not both');
|
|
58
|
+
process.exit(2);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (rootURL) {
|
|
62
|
+
rootURL = trimSlash(rootURL);
|
|
63
|
+
baseURL = `${rootURL}/bin/targets`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (scriptRootURL) {
|
|
67
|
+
scriptRootURL = trimSlash(scriptRootURL);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function copyFile(src, dest) {
|
|
71
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
72
|
+
fs.copyFileSync(src, dest);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function writeFile(dest, content) {
|
|
76
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
77
|
+
fs.writeFileSync(dest, content);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function normalizeGeneratedAt(value) {
|
|
81
|
+
if (!value) {
|
|
82
|
+
return new Date().toISOString();
|
|
83
|
+
}
|
|
84
|
+
const parsed = new Date(value);
|
|
85
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
86
|
+
console.error(`invalid SKILL_CLI_BUNDLE_GENERATED_AT: ${value}`);
|
|
87
|
+
process.exit(2);
|
|
88
|
+
}
|
|
89
|
+
return parsed.toISOString();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fs.rmSync(outDir, { recursive: true, force: true });
|
|
93
|
+
|
|
94
|
+
for (const target of targets) {
|
|
95
|
+
const src = path.join(rootDir, 'bin', 'targets', target);
|
|
96
|
+
if (!fs.existsSync(src)) {
|
|
97
|
+
console.error(`missing binary: ${src}`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
copyFile(src, path.join(outDir, 'bin', 'targets', target));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let installSH = fs.readFileSync(path.join(rootDir, 'scripts', 'install.sh'), 'utf8');
|
|
104
|
+
let installPS1 = fs.readFileSync(path.join(rootDir, 'scripts', 'install.ps1'), 'utf8');
|
|
105
|
+
|
|
106
|
+
installSH = installSH.replace(/DEFAULT_VERSION="[^"]+"/, `DEFAULT_VERSION="${version}"`);
|
|
107
|
+
installSH = installSH.replace(
|
|
108
|
+
/SKILL_CLI_VERSION Same as --version\. Default: [^\n]+/,
|
|
109
|
+
`SKILL_CLI_VERSION Same as --version. Default: ${version}.`
|
|
110
|
+
);
|
|
111
|
+
installPS1 = installPS1.replace(/\$Version = "[^"]+"/, `$Version = "${version}"`);
|
|
112
|
+
|
|
113
|
+
if (baseURL) {
|
|
114
|
+
const normalizedBaseURL = trimSlash(baseURL);
|
|
115
|
+
installSH = installSH.replace(
|
|
116
|
+
/DEFAULT_BASE_URL="https:\/\/gitee\.com\/marvin-dev\/skill-cli-release\/raw\/\$\{VERSION\}\/bin\/targets"/,
|
|
117
|
+
`DEFAULT_BASE_URL="${normalizedBaseURL}"`
|
|
118
|
+
).replace(
|
|
119
|
+
/DEFAULT_BASE_URL_USES_VERSION=1/,
|
|
120
|
+
'DEFAULT_BASE_URL_USES_VERSION=0'
|
|
121
|
+
);
|
|
122
|
+
installPS1 = installPS1.replace(
|
|
123
|
+
/\$BaseUrl = "https:\/\/gitee\.com\/marvin-dev\/skill-cli-release\/raw\/\$Version\/bin\/targets"/,
|
|
124
|
+
`$BaseUrl = "${normalizedBaseURL}"`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
writeFile(path.join(outDir, 'scripts', 'install.sh'), installSH);
|
|
129
|
+
writeFile(path.join(outDir, 'scripts', 'install.ps1'), installPS1);
|
|
130
|
+
|
|
131
|
+
const manifest = {
|
|
132
|
+
package: pkg.name,
|
|
133
|
+
version: pkg.version,
|
|
134
|
+
tag: version,
|
|
135
|
+
generatedAt,
|
|
136
|
+
rootURL: rootURL || null,
|
|
137
|
+
scriptRootURL: scriptRootURL || null,
|
|
138
|
+
baseURL: baseURL || null,
|
|
139
|
+
files: [
|
|
140
|
+
'scripts/install.ps1',
|
|
141
|
+
'scripts/install.sh',
|
|
142
|
+
...targets.map((target) => `bin/targets/${target}`),
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
writeFile(path.join(outDir, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
146
|
+
|
|
147
|
+
function inferInstallRootFromBaseURL(value) {
|
|
148
|
+
const normalized = trimSlash(value);
|
|
149
|
+
if (normalized.endsWith('/bin/targets')) {
|
|
150
|
+
return normalized.slice(0, -'/bin/targets'.length);
|
|
151
|
+
}
|
|
152
|
+
return '<your-hosted-root>';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const installRoot = scriptRootURL || rootURL || (baseURL ? inferInstallRootFromBaseURL(baseURL) : `https://gitee.com/marvin-dev/skill-cli-release/raw/${version}`);
|
|
156
|
+
const psURL = baseURL ? `${installRoot}/scripts/install.ps1` : `${installRoot}/scripts/install.ps1`;
|
|
157
|
+
const shURL = baseURL ? `${installRoot}/scripts/install.sh` : `${installRoot}/scripts/install.sh`;
|
|
158
|
+
|
|
159
|
+
writeFile(path.join(outDir, 'README.txt'), `skill-cli ${version} install bundle
|
|
160
|
+
|
|
161
|
+
Host this directory as a static tree. Required layout:
|
|
162
|
+
scripts/install.ps1
|
|
163
|
+
scripts/install.sh
|
|
164
|
+
bin/targets/skill-cli-*
|
|
165
|
+
|
|
166
|
+
Windows PowerShell:
|
|
167
|
+
irm ${psURL} | iex
|
|
168
|
+
|
|
169
|
+
macOS/Linux:
|
|
170
|
+
curl -fsSL ${shURL} | bash
|
|
171
|
+
|
|
172
|
+
If --base-url was not used to generate this bundle, set SKILL_CLI_BASE_URL
|
|
173
|
+
to the hosted bin/targets URL before running the installer.
|
|
174
|
+
`);
|
|
175
|
+
|
|
176
|
+
console.log(`Created ${outDir}`);
|
|
177
|
+
console.log(`Version: ${version}`);
|
|
178
|
+
if (baseURL) {
|
|
179
|
+
console.log(`Default binary base URL: ${baseURL}`);
|
|
180
|
+
}
|