@songsid/agend 2.3.2-beta.5 → 2.3.2-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.
- package/dist/backend/kiro-identity.d.ts +11 -0
- package/dist/backend/kiro-identity.js +16 -0
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-retired-model.d.ts +62 -0
- package/dist/backend/kiro-retired-model.js +160 -0
- package/dist/backend/kiro-retired-model.js.map +1 -0
- package/dist/backend/kiro.d.ts +17 -0
- package/dist/backend/kiro.js +77 -1
- package/dist/backend/kiro.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +11 -0
- package/dist/channel/adapters/discord.js +64 -10
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/config-validator.js +25 -3
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.js +5 -0
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +21 -5
- package/dist/fleet-manager.js +154 -133
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +14 -1
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +14 -1
- package/dist/instance-lifecycle.d.ts +2 -0
- package/dist/instance-lifecycle.js +23 -8
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +16 -0
- package/dist/locale.js.map +1 -1
- package/dist/notice-delivery.d.ts +7 -6
- package/dist/notice-delivery.js +16 -18
- package/dist/notice-delivery.js.map +1 -1
- package/dist/office-share-page.d.ts +13 -0
- package/dist/office-share-page.js +82 -0
- package/dist/office-share-page.js.map +1 -0
- package/dist/office-share-service.d.ts +89 -0
- package/dist/office-share-service.js +172 -0
- package/dist/office-share-service.js.map +1 -0
- package/dist/office-share.d.ts +228 -0
- package/dist/office-share.js +489 -0
- package/dist/office-share.js.map +1 -0
- package/dist/public-web-gateway.js +6 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart.js +0 -2
- package/dist/quickstart.js.map +1 -1
- package/dist/settings-api.js +1 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +48 -5
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-host.js +4 -3
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +0 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/types.d.ts +12 -3
- package/dist/ui/fleet-office-pack.js +7 -2
- package/dist/ui/fleet-office-skin.js +5 -4
- package/dist/ui/fleet-office-zones.js +17 -6
- package/dist/ui/fleet-office.js +20 -10
- package/dist/ui/office-share-dialog.js +145 -0
- package/dist/ui/office-share-page.js +116 -0
- package/dist/ui/panel-settings.js +12 -8
- package/dist/ui/settings-registry.js +2 -2
- package/dist/ui/settings-strings.js +6 -6
- package/dist/ui/shared/app.css +28 -0
- package/dist/web-api.d.ts +14 -0
- package/dist/web-api.js +91 -0
- package/dist/web-api.js.map +1 -1
- package/dist/web-office-skins.d.ts +2 -1
- package/dist/web-office-skins.js +2 -1
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-settings-patch.js +1 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/working-recovery.d.ts +2 -2
- package/dist/working-recovery.js +43 -8
- package/dist/working-recovery.js.map +1 -1
- package/dist/working-state-journal.d.ts +2 -0
- package/dist/working-state-journal.js +16 -1
- package/dist/working-state-journal.js.map +1 -1
- package/package.json +1 -1
- package/templates/windows-shortcuts.ps1 +151 -147
|
@@ -3,190 +3,194 @@
|
|
|
3
3
|
# (tests/windows-shortcuts-cli-1853.test.ts 檢查):改的時候兩邊一起改。
|
|
4
4
|
|
|
5
5
|
$WSL_COMMAND_FN = @'
|
|
6
|
+
function Invoke-BoundedWsl {
|
|
7
|
+
param([string[]]$Arguments, [int]$TimeoutSeconds = 30)
|
|
8
|
+
$sep = [array]::IndexOf($Arguments, '--')
|
|
9
|
+
if ($sep -ge 0 -and $Arguments.Length -gt ($sep + 1) -and $Arguments[$sep + 1] -eq 'bash') {
|
|
10
|
+
$Arguments = @($Arguments[0..$sep]) + @('timeout', '--signal=TERM', '--kill-after=2s', [string]([Math]::Max(1, $TimeoutSeconds - 5))) + @($Arguments[($sep + 1)..($Arguments.Length - 1)])
|
|
11
|
+
}
|
|
12
|
+
$p = New-Object Diagnostics.Process
|
|
13
|
+
$p.StartInfo.FileName = 'wsl.exe'
|
|
14
|
+
$p.StartInfo.Arguments = (@($Arguments | ForEach-Object { if ($_ -match '[\s"]') { '"' + ($_ -replace '"', '\"') + '"' } else { $_ } }) -join ' ')
|
|
15
|
+
$p.StartInfo.UseShellExecute = $false; $p.StartInfo.CreateNoWindow = $true
|
|
16
|
+
$p.StartInfo.StandardOutputEncoding = [Text.Encoding]::UTF8; $p.StartInfo.StandardErrorEncoding = [Text.Encoding]::UTF8
|
|
17
|
+
$p.StartInfo.RedirectStandardOutput = $true; $p.StartInfo.RedirectStandardError = $true; $p.StartInfo.RedirectStandardInput = $true
|
|
18
|
+
try {
|
|
19
|
+
$null = $p.Start(); $p.StandardInput.Close()
|
|
20
|
+
$out = $p.StandardOutput.ReadToEndAsync(); $err = $p.StandardError.ReadToEndAsync()
|
|
21
|
+
if (-not $p.WaitForExit($TimeoutSeconds * 1000)) {
|
|
22
|
+
$p.Kill(); $null = $p.WaitForExit(10000)
|
|
23
|
+
return @{Code=124;Text='WSL timed out; check it before retrying.'}
|
|
24
|
+
}
|
|
25
|
+
if (-not $out.Wait(1000) -or -not $err.Wait(1000)) { return @{Code=1;Text='WSL output did not close.'} }
|
|
26
|
+
$text = $out.Result + $err.Result
|
|
27
|
+
if ($text.Length -gt 1MB) { return @{Code=1;Text='WSL output exceeded its limit.'} }
|
|
28
|
+
return @{Code=$p.ExitCode;Text=$text}
|
|
29
|
+
} catch { return @{Code=-1;Text=[string]$_} }
|
|
30
|
+
finally { $p.Dispose() }
|
|
31
|
+
}
|
|
6
32
|
function Get-WslAgendCommand([string]$command) {
|
|
7
|
-
|
|
33
|
+
return ('export PATH=$HOME/.local/bin:$PATH; source $HOME/.nvm/nvm.sh 2>/dev/null; ' + $command)
|
|
8
34
|
}
|
|
9
|
-
# 放進 PowerShell 文字裡的值(Linux、使用者名稱)一律用這個轉成字面字串:名稱裡的單引號(例如 o'neil)不會讓產生的
|
|
10
|
-
# 腳本或貼上的指令壞掉(#2260 審查)。印給人看的指令,名稱沒有特殊字元時維持原樣、不加引號。
|
|
11
35
|
function ConvertTo-PsLiteral([string]$value) { return ("'" + ($value -replace "'", "''") + "'") }
|
|
12
36
|
function ConvertTo-PsArgument([string]$value) { if ($value -match '^[\w.-]+$') { return $value } else { return (ConvertTo-PsLiteral $value) } }
|
|
13
37
|
function Get-AgendStartHint([string]$distro, [string]$user) {
|
|
14
|
-
|
|
38
|
+
return ("wsl -d {0} -u {1} -- bash -lc '{2}'" -f (ConvertTo-PsArgument $distro), (ConvertTo-PsArgument $user), (Get-WslAgendCommand 'agend start'))
|
|
15
39
|
}
|
|
16
40
|
'@
|
|
17
41
|
. ([scriptblock]::Create($WSL_COMMAND_FN))
|
|
18
|
-
|
|
19
42
|
$DASHBOARD_OPENER_FN = @'
|
|
20
43
|
function Get-DashboardSignIn([string]$text) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
44
|
+
$url = [regex]::Match($text, 'Sign-in page:\s*(https?://\S+)')
|
|
45
|
+
$code = [regex]::Match($text, 'Code:\s*([A-Z2-7]{4}-?[A-Z2-7]{4})\b')
|
|
46
|
+
if (-not $url.Success -or -not $code.Success) { return $null }
|
|
47
|
+
return @{ Url = $url.Groups[1].Value; Code = $code.Groups[1].Value }
|
|
25
48
|
}
|
|
26
49
|
function Invoke-OpenDashboard([string]$distro, [string]$user = 'root', [switch]$Wait, [string]$BackendSignins = '') {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
$command = 'agend web --code'
|
|
51
|
+
if ($BackendSignins) {
|
|
52
|
+
if ($BackendSignins -cnotmatch '^(kiro-cli|claude-code|codex|antigravity)(,(kiro-cli|claude-code|codex|antigravity)){0,3}\z') { throw 'Invalid backend selection' }
|
|
53
|
+
$command += ' --backend-signins ' + $BackendSignins
|
|
54
|
+
}
|
|
55
|
+
$text = ''; $exit = 1
|
|
56
|
+
$prevEAP = $ErrorActionPreference
|
|
57
|
+
try {
|
|
58
|
+
$ErrorActionPreference = 'Continue'
|
|
59
|
+
$r = Invoke-BoundedWsl -Arguments @('-d', $distro, '-u', $user, '--', 'bash', '-lc', (Get-WslAgendCommand $command))
|
|
60
|
+
$text = $r.Text; $exit = $r.Code
|
|
61
|
+
} catch {
|
|
62
|
+
$text = "$_"; $exit = 1
|
|
63
|
+
} finally {
|
|
64
|
+
$ErrorActionPreference = $prevEAP
|
|
65
|
+
}
|
|
66
|
+
$signIn = if ($exit -eq 0) { Get-DashboardSignIn $text } else { $null }
|
|
67
|
+
if (-not $signIn) {
|
|
68
|
+
Write-Host " [!!] 現在打不開 AgEnD 儀表板:AgEnD 可能還沒啟動。" -ForegroundColor Yellow
|
|
69
|
+
Write-Host (" 稍等一下再試一次;或在 PowerShell 執行:" + (Get-AgendStartHint $distro $user))
|
|
70
|
+
if ($Wait) { Read-Host "按 Enter 關閉" }
|
|
71
|
+
return $false
|
|
72
|
+
}
|
|
73
|
+
$copied = $false; try { Set-Clipboard -Value $signIn.Code; $copied = $true } catch { }
|
|
74
|
+
$opened = $false; try { Start-Process $signIn.Url; $opened = $true } catch { }
|
|
75
|
+
$spaced = ($signIn.Code.ToCharArray() | ForEach-Object { [string]$_ }) -join ' '
|
|
76
|
+
Write-Host ""
|
|
77
|
+
Write-Host (" ┌──────────────────────────────────────┐") -ForegroundColor Green
|
|
78
|
+
Write-Host (" │ 儀表板登入碼: " + $spaced + " │") -ForegroundColor Green
|
|
79
|
+
Write-Host (" └──────────────────────────────────────┘") -ForegroundColor Green
|
|
80
|
+
if ($opened) { Write-Host " [OK] 登入頁已在瀏覽器打開。" -ForegroundColor Green }
|
|
81
|
+
Write-Host (" 登入頁網址:" + $signIn.Url)
|
|
82
|
+
if ($copied) { Write-Host " [OK] 登入碼已複製:在登入頁的輸入框按 Ctrl+V。這組登入碼只能用一次,幾分鐘內有效。" -ForegroundColor Green }
|
|
83
|
+
else { Write-Host " 在登入頁輸入上面的登入碼。這組登入碼只能用一次,幾分鐘內有效。" }
|
|
84
|
+
if ($Wait) { Read-Host "按 Enter 關閉" }
|
|
85
|
+
return $true
|
|
62
86
|
}
|
|
63
87
|
'@
|
|
64
88
|
. ([scriptblock]::Create($DASHBOARD_OPENER_FN))
|
|
65
|
-
|
|
66
|
-
# 「AgEnD 重新啟動」捷徑(#1853,使用者 2026-10-20 核准):先問,預設不重啟;確定才在安裝時記下的 Linux 和使用者裡執行
|
|
67
|
-
# agend restart,接著顯示 agend status,等你按 Enter。WSL 或 AgEnD 不在時直接說明;絕不執行 wsl --shutdown。
|
|
68
|
-
# 這段函式的文字同時是捷徑執行的腳本(和儀表板捷徑一樣,安裝程式與捷徑共用同一份)。
|
|
69
89
|
$RESTART_FN = @'
|
|
70
90
|
function Invoke-AgendInWsl([string]$distro, [string]$user, [string]$command) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
91
|
+
$prevEAP = $ErrorActionPreference; $prevEnc = [Console]::OutputEncoding
|
|
92
|
+
try {
|
|
93
|
+
$ErrorActionPreference = 'Continue'
|
|
94
|
+
try { [Console]::OutputEncoding = [Text.Encoding]::UTF8 } catch { }
|
|
95
|
+
$limit = if ($command -match '^agend (restart|start)( |$)') { 360 } else { 30 }
|
|
96
|
+
return (Invoke-BoundedWsl -TimeoutSeconds $limit -Arguments @('-d', $distro, '-u', $user, '--', 'bash', '-lc', (Get-WslAgendCommand $command)))
|
|
97
|
+
} catch {
|
|
98
|
+
return @{ Code = -1; Text = "$_" }
|
|
99
|
+
} finally {
|
|
100
|
+
$ErrorActionPreference = $prevEAP
|
|
101
|
+
try { [Console]::OutputEncoding = $prevEnc } catch { }
|
|
102
|
+
}
|
|
84
103
|
}
|
|
85
104
|
function Invoke-RestartAgend([string]$distro, [string]$user, [switch]$Wait, [int]$SettleSeconds = 3) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return $result
|
|
105
|
+
Write-Host ""
|
|
106
|
+
$answer = Read-Host " 確定要重啟 AgEnD 嗎?所有 agent 會重新啟動,正在進行的工作會中斷。(y/N)"
|
|
107
|
+
if (([string]$answer) -notmatch '^\s*[yY]\s*$') {
|
|
108
|
+
Write-Host " 沒有重啟。"
|
|
109
|
+
if ($Wait) { $null = Read-Host "按 Enter 關閉" }
|
|
110
|
+
return 'cancelled'
|
|
111
|
+
}
|
|
112
|
+
$r = Invoke-AgendInWsl $distro $user 'agend restart'
|
|
113
|
+
$result = 'restarted'
|
|
114
|
+
if ($r.Code -eq 0) {
|
|
115
|
+
Write-Host " [OK] AgEnD 正在重新啟動。" -ForegroundColor Green
|
|
116
|
+
} else {
|
|
117
|
+
$result = 'failed'
|
|
118
|
+
if ($r.Code -eq -1) { Write-Host " [!!] 找不到 WSL(wsl.exe),所以沒有重啟。" -ForegroundColor Yellow }
|
|
119
|
+
elseif ($r.Text -match 'Fleet not running') { Write-Host (" [!!] AgEnD 沒有在執行,所以沒有可以重啟的。要啟動它:" + (Get-AgendStartHint $distro $user)) -ForegroundColor Yellow }
|
|
120
|
+
elseif ($r.Text -match 'command not found|agend: not found|no such file') { Write-Host (" [!!] 在 {0} 裡找不到 AgEnD(agend 指令),所以沒有重啟。" -f $distro) -ForegroundColor Yellow }
|
|
121
|
+
else { Write-Host (" [!!] 沒有重啟成功:{0} 不存在、WSL 沒有啟動,或 AgEnD 回報了錯誤。" -f $distro) -ForegroundColor Yellow }
|
|
122
|
+
if ($r.Text.Trim()) { Write-Host (" " + ($r.Text.Trim() -replace "`r?`n", "`n ")) }
|
|
123
|
+
}
|
|
124
|
+
if ($result -eq 'restarted') {
|
|
125
|
+
Start-Sleep -Seconds $SettleSeconds
|
|
126
|
+
Write-Host ""
|
|
127
|
+
$s = Invoke-AgendInWsl $distro $user 'agend status'
|
|
128
|
+
if ($s.Text.Trim()) { Write-Host (" " + ($s.Text.Trim() -replace "`r?`n", "`n ")) }
|
|
129
|
+
}
|
|
130
|
+
if ($Wait) { $null = Read-Host "按 Enter 關閉" }
|
|
131
|
+
return $result
|
|
114
132
|
}
|
|
115
133
|
'@
|
|
116
134
|
. ([scriptblock]::Create($RESTART_FN))
|
|
117
|
-
|
|
118
|
-
# 捷徑執行的腳本:共用的函式加上一行呼叫(UTF-8 有 BOM:Windows PowerShell 5.1 才會正確顯示中文)。Linux 與使用者是安裝時記下的。
|
|
119
|
-
# 捷徑腳本印出的第一行:它要打開的 Linux 和使用者,指錯了一眼就看得出來。
|
|
120
135
|
function Get-ShortcutTargetLine([string]$distro, [string]$user) {
|
|
121
|
-
|
|
136
|
+
return ('Write-Host ("AgEnD(Linux:{0},使用者:{1})" -f ' + (ConvertTo-PsLiteral $distro) + ', ' + (ConvertTo-PsLiteral $user) + ')')
|
|
122
137
|
}
|
|
123
138
|
function Get-DashboardOpenerScript([string]$distro, [string]$user) {
|
|
124
|
-
|
|
139
|
+
return ("# AgEnD 儀表板(AgEnD 安裝程式建立)`n" + (Get-ShortcutTargetLine $distro $user) + "`n" + $WSL_COMMAND_FN + "`n" + $DASHBOARD_OPENER_FN + "`n" + ("Invoke-OpenDashboard {0} {1} -Wait | Out-Null" -f (ConvertTo-PsLiteral $distro), (ConvertTo-PsLiteral $user)) + "`n")
|
|
125
140
|
}
|
|
126
141
|
function Get-RestartScript([string]$distro, [string]$user) {
|
|
127
|
-
|
|
142
|
+
return ("# AgEnD 重新啟動(AgEnD 安裝程式建立)`n" + (Get-ShortcutTargetLine $distro $user) + "`n" + $WSL_COMMAND_FN + "`n" + $RESTART_FN + "`n" + ("Invoke-RestartAgend {0} {1} -Wait | Out-Null" -f (ConvertTo-PsLiteral $distro), (ConvertTo-PsLiteral $user)) + "`n")
|
|
128
143
|
}
|
|
129
|
-
# 安裝時記下的 Linux 與使用者(%LOCALAPPDATA%\AgEnD\install.json):捷徑、重新執行安裝指令時的快速路徑都讀它。
|
|
130
144
|
function Get-AgendShortcutDir { return (Join-Path $env:LOCALAPPDATA 'AgEnD') }
|
|
131
145
|
function Read-InstallRecord {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
# install.json 已經指向另一個 Linux 或使用者時回傳那筆紀錄(例如 AgEnD 專用的 Linux 和原本的 Ubuntu),否則 $null。
|
|
139
|
-
# 捷徑絕不悄悄改指向:agend shortcuts 遇到這種情況會先問。
|
|
146
|
+
try {
|
|
147
|
+
$r = Get-Content -Raw -LiteralPath (Join-Path (Get-AgendShortcutDir) 'install.json') -ErrorAction Stop | ConvertFrom-Json
|
|
148
|
+
if ($r.distro -and $r.user) { return @{ Distro = [string]$r.distro; User = [string]$r.user } }
|
|
149
|
+
} catch { }
|
|
150
|
+
return $null
|
|
151
|
+
}
|
|
140
152
|
function Get-InstallRecordConflict([string]$distro, [string]$user) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return $null
|
|
153
|
+
$record = Read-InstallRecord
|
|
154
|
+
if ($record -and ($record.Distro -ne $distro -or $record.User -cne $user)) { return $record }
|
|
155
|
+
return $null
|
|
145
156
|
}
|
|
146
|
-
# 真正寫入前再讀一次:詢問時看到的是 $seen($null:當時沒有衝突)。現在沒有衝突,或衝突的還是同一個,才可以寫;
|
|
147
|
-
# 在等回答的時候被別的安裝程式或終端機改掉了,就不寫(#2279 審查)。
|
|
148
157
|
function Test-InstallRecordAsSeen($seen, [string]$distro, [string]$user) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
158
|
+
$now = Get-InstallRecordConflict $distro $user
|
|
159
|
+
if ($null -eq $now) { return $true }
|
|
160
|
+
return ($null -ne $seen -and $now.Distro -eq $seen.Distro -and $now.User -ceq $seen.User)
|
|
152
161
|
}
|
|
153
|
-
# 有 Windows Terminal 時捷徑在它裡面開(中文顯示較好);沒有或 AGEND_INSTALL_TERMINAL=conhost 時直接開 PowerShell。
|
|
154
162
|
function Get-ShortcutCommand([string]$file) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
$ps = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
|
|
164
|
+
$a = '-NoProfile -ExecutionPolicy Bypass -File "{0}"' -f $file
|
|
165
|
+
$wt = $null; if ($env:AGEND_INSTALL_TERMINAL -ne 'conhost') { $wt = Get-Command wt.exe -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1 }
|
|
166
|
+
if ($wt) { return @{ Target = $wt.Source; Arguments = '-w new "{0}" {1}' -f $ps, ($a -replace ';', '\;') } }
|
|
167
|
+
return @{ Target = $ps; Arguments = $a }
|
|
160
168
|
}
|
|
161
|
-
# 一個桌面捷徑:腳本寫在 %LOCALAPPDATA%\AgEnD,捷徑以 Windows PowerShell 執行它(-ExecutionPolicy Bypass 只對那個行程)。
|
|
162
169
|
function New-AgendShortcut([string]$name, [string]$scriptName, [string]$scriptText, [string]$description) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
# 建立(或更新)兩個桌面捷徑、記下 Linux 與使用者。兩個各自建立,一個失敗不會擋住另一個;回傳建立好的捷徑路徑,
|
|
178
|
-
# 呼叫端用 Write-ShortcutResult 分清楚兩個都好、只好一個、都沒好(#2252 審查)。兩個都好才在 WSL 裡留記號(agend update
|
|
179
|
-
# 之後的提示就不會再出現)。不是 Windows 時回傳空陣列。
|
|
170
|
+
$dir = Get-AgendShortcutDir
|
|
171
|
+
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
|
172
|
+
$file = Join-Path $dir $scriptName
|
|
173
|
+
[IO.File]::WriteAllText($file, $scriptText, (New-Object System.Text.UTF8Encoding $true))
|
|
174
|
+
$lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) ($name + '.lnk')
|
|
175
|
+
$shell = New-Object -ComObject WScript.Shell
|
|
176
|
+
$sc = $shell.CreateShortcut($lnk)
|
|
177
|
+
$cmd = Get-ShortcutCommand $file
|
|
178
|
+
$sc.TargetPath = $cmd.Target
|
|
179
|
+
$sc.Arguments = $cmd.Arguments
|
|
180
|
+
$sc.Description = $description
|
|
181
|
+
$sc.Save()
|
|
182
|
+
return $lnk
|
|
183
|
+
}
|
|
180
184
|
function Install-AgendShortcuts([string]$distro, [string]$user) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
185
|
+
if (-not $script:OnWindows) { return @() }
|
|
186
|
+
$made = @()
|
|
187
|
+
try { $made += New-AgendShortcut 'AgEnD 儀表板' 'open-dashboard.ps1' (Get-DashboardOpenerScript $distro $user) 'AgEnD 網頁儀表板(自動帶入登入碼)' } catch { }
|
|
188
|
+
try { $made += New-AgendShortcut 'AgEnD 重新啟動' 'restart-agend.ps1' (Get-RestartScript $distro $user) '重新啟動 AgEnD(會先詢問)' } catch { }
|
|
189
|
+
try {
|
|
190
|
+
New-Item -ItemType Directory -Path (Get-AgendShortcutDir) -Force | Out-Null
|
|
191
|
+
$record = @{ distro = $distro; user = $user } | ConvertTo-Json -Compress
|
|
192
|
+
[IO.File]::WriteAllText((Join-Path (Get-AgendShortcutDir) 'install.json'), $record, (New-Object System.Text.UTF8Encoding $false))
|
|
193
|
+
if ($made.Count -eq 2) { $null = Invoke-AgendInWsl $distro $user 'set -f; IFS=; d=${AGEND_HOME:-$HOME/.agend}; umask 077; mkdir -p -m 700 -- $d && date -u +%FT%TZ > $d/windows-shortcuts' }
|
|
194
|
+
} catch { }
|
|
191
195
|
return $made
|
|
192
196
|
}
|