ancoder-skill-cli 0.13.38-beta.5 → 0.13.38-beta.7

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.
@@ -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
+ }