@songsid/agend 2.3.1 → 2.3.2-beta.10

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 (338) hide show
  1. package/THIRD_PARTY_NOTICES.md +40 -0
  2. package/dist/agent-cli.js +21 -2
  3. package/dist/agent-cli.js.map +1 -1
  4. package/dist/agent-endpoint.js +5 -0
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/antigravity-usage-scan.d.ts +58 -0
  7. package/dist/antigravity-usage-scan.js +257 -0
  8. package/dist/antigravity-usage-scan.js.map +1 -0
  9. package/dist/antigravity-usage-worker.d.ts +1 -0
  10. package/dist/antigravity-usage-worker.js +10 -0
  11. package/dist/antigravity-usage-worker.js.map +1 -0
  12. package/dist/auth-api.js +4 -0
  13. package/dist/auth-api.js.map +1 -1
  14. package/dist/authority/authority-state.d.ts +4 -0
  15. package/dist/authority/authority-state.js +16 -10
  16. package/dist/authority/authority-state.js.map +1 -1
  17. package/dist/authority/session-authorizations.d.ts +7 -1
  18. package/dist/authority/session-authorizations.js +6 -4
  19. package/dist/authority/session-authorizations.js.map +1 -1
  20. package/dist/authority/web-authority.d.ts +19 -6
  21. package/dist/authority/web-authority.js +22 -8
  22. package/dist/authority/web-authority.js.map +1 -1
  23. package/dist/backend/kiro-identity.d.ts +64 -0
  24. package/dist/backend/kiro-identity.js +101 -0
  25. package/dist/backend/kiro-identity.js.map +1 -1
  26. package/dist/backend/kiro-retired-model.d.ts +62 -0
  27. package/dist/backend/kiro-retired-model.js +160 -0
  28. package/dist/backend/kiro-retired-model.js.map +1 -0
  29. package/dist/backend/kiro.d.ts +71 -2
  30. package/dist/backend/kiro.js +352 -11
  31. package/dist/backend/kiro.js.map +1 -1
  32. package/dist/backend/types.d.ts +59 -0
  33. package/dist/backend/types.js.map +1 -1
  34. package/dist/backend-signin-guide.d.ts +1 -0
  35. package/dist/backend-signin-guide.js +9 -0
  36. package/dist/backend-signin-guide.js.map +1 -0
  37. package/dist/backend-signin-pending.d.ts +10 -0
  38. package/dist/backend-signin-pending.js +44 -0
  39. package/dist/backend-signin-pending.js.map +1 -0
  40. package/dist/browser-backend-signins.d.ts +56 -0
  41. package/dist/browser-backend-signins.js +189 -0
  42. package/dist/browser-backend-signins.js.map +1 -0
  43. package/dist/cache-ledger.d.ts +38 -2
  44. package/dist/cache-ledger.js +133 -8
  45. package/dist/cache-ledger.js.map +1 -1
  46. package/dist/cache-prices.d.ts +2 -1
  47. package/dist/cache-prices.js +5 -2
  48. package/dist/cache-prices.js.map +1 -1
  49. package/dist/cache-service.d.ts +68 -0
  50. package/dist/cache-service.js +355 -13
  51. package/dist/cache-service.js.map +1 -1
  52. package/dist/channel/adapters/discord.d.ts +13 -0
  53. package/dist/channel/adapters/discord.js +103 -16
  54. package/dist/channel/adapters/discord.js.map +1 -1
  55. package/dist/channel/mcp-tools.js +34 -7
  56. package/dist/channel/mcp-tools.js.map +1 -1
  57. package/dist/channel/tool-router.js +2 -1
  58. package/dist/channel/tool-router.js.map +1 -1
  59. package/dist/channel/types.d.ts +11 -0
  60. package/dist/classic-channel-manager.d.ts +11 -0
  61. package/dist/classic-channel-manager.js +39 -1
  62. package/dist/classic-channel-manager.js.map +1 -1
  63. package/dist/cli.js +21 -2
  64. package/dist/cli.js.map +1 -1
  65. package/dist/config-validator.d.ts +7 -1
  66. package/dist/config-validator.js +92 -12
  67. package/dist/config-validator.js.map +1 -1
  68. package/dist/config.d.ts +19 -0
  69. package/dist/config.js +31 -1
  70. package/dist/config.js.map +1 -1
  71. package/dist/cpu-quota.d.ts +23 -0
  72. package/dist/cpu-quota.js +86 -0
  73. package/dist/cpu-quota.js.map +1 -0
  74. package/dist/daemon.d.ts +57 -3
  75. package/dist/daemon.js +330 -50
  76. package/dist/daemon.js.map +1 -1
  77. package/dist/dashboard-permissions.d.ts +20 -6
  78. package/dist/dashboard-permissions.js +58 -9
  79. package/dist/dashboard-permissions.js.map +1 -1
  80. package/dist/delivery-outbox.d.ts +12 -1
  81. package/dist/delivery-outbox.js +67 -15
  82. package/dist/delivery-outbox.js.map +1 -1
  83. package/dist/doctor.d.ts +3 -0
  84. package/dist/doctor.js +11 -1
  85. package/dist/doctor.js.map +1 -1
  86. package/dist/event-log.d.ts +5 -0
  87. package/dist/event-log.js +13 -0
  88. package/dist/event-log.js.map +1 -1
  89. package/dist/fleet-manager.d.ts +212 -0
  90. package/dist/fleet-manager.js +914 -111
  91. package/dist/fleet-manager.js.map +1 -1
  92. package/dist/fleet-process-handlers.d.ts +1 -0
  93. package/dist/fleet-process-handlers.js +9 -1
  94. package/dist/fleet-process-handlers.js.map +1 -1
  95. package/dist/forged-envelope-scan.d.ts +9 -0
  96. package/dist/forged-envelope-scan.js +30 -5
  97. package/dist/forged-envelope-scan.js.map +1 -1
  98. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +5 -2
  99. package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +14 -1
  100. package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +28 -5
  101. package/dist/general-knowledge/skills/web-appearance/SKILL.md +31 -8
  102. package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +138 -59
  103. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +145 -61
  104. package/dist/guest-seen-people.d.ts +38 -0
  105. package/dist/guest-seen-people.js +78 -0
  106. package/dist/guest-seen-people.js.map +1 -0
  107. package/dist/instance-config-impact.js +14 -6
  108. package/dist/instance-config-impact.js.map +1 -1
  109. package/dist/instance-lifecycle.d.ts +20 -0
  110. package/dist/instance-lifecycle.js +71 -13
  111. package/dist/instance-lifecycle.js.map +1 -1
  112. package/dist/kiro-db-reader.d.ts +5 -0
  113. package/dist/kiro-db-reader.js +18 -0
  114. package/dist/kiro-db-reader.js.map +1 -1
  115. package/dist/kiro-engine-status.d.ts +2 -0
  116. package/dist/kiro-engine-status.js +9 -0
  117. package/dist/kiro-engine-status.js.map +1 -1
  118. package/dist/kiro-migrate.d.ts +49 -0
  119. package/dist/kiro-migrate.js +105 -0
  120. package/dist/kiro-migrate.js.map +1 -0
  121. package/dist/kiro-transcript-lane.d.ts +2 -0
  122. package/dist/kiro-transcript-lane.js.map +1 -1
  123. package/dist/kiro-transcript-worker.js +1 -0
  124. package/dist/kiro-transcript-worker.js.map +1 -1
  125. package/dist/kiro-tui-forensic.d.ts +7 -0
  126. package/dist/kiro-tui-forensic.js +110 -0
  127. package/dist/kiro-tui-forensic.js.map +1 -0
  128. package/dist/kiro-usage-run.d.ts +7 -0
  129. package/dist/kiro-usage-run.js +39 -0
  130. package/dist/kiro-usage-run.js.map +1 -0
  131. package/dist/kiro-usage-scan.d.ts +49 -0
  132. package/dist/kiro-usage-scan.js +223 -0
  133. package/dist/kiro-usage-scan.js.map +1 -0
  134. package/dist/kiro-usage-worker.d.ts +1 -0
  135. package/dist/kiro-usage-worker.js +10 -0
  136. package/dist/kiro-usage-worker.js.map +1 -0
  137. package/dist/kiro-usage.d.ts +58 -0
  138. package/dist/kiro-usage.js +310 -0
  139. package/dist/kiro-usage.js.map +1 -0
  140. package/dist/locale.js +120 -12
  141. package/dist/locale.js.map +1 -1
  142. package/dist/log-service.js +1 -1
  143. package/dist/log-service.js.map +1 -1
  144. package/dist/login-url.d.ts +4 -0
  145. package/dist/login-url.js +22 -0
  146. package/dist/login-url.js.map +1 -0
  147. package/dist/mac-auto-restore.d.ts +117 -0
  148. package/dist/mac-auto-restore.js +294 -0
  149. package/dist/mac-auto-restore.js.map +1 -0
  150. package/dist/needs-you-hub.d.ts +2 -1
  151. package/dist/needs-you-hub.js +1 -1
  152. package/dist/needs-you-hub.js.map +1 -1
  153. package/dist/needs-you.d.ts +8 -2
  154. package/dist/needs-you.js +6 -0
  155. package/dist/needs-you.js.map +1 -1
  156. package/dist/notice-delivery.d.ts +16 -0
  157. package/dist/notice-delivery.js +35 -0
  158. package/dist/notice-delivery.js.map +1 -0
  159. package/dist/office-share-page.d.ts +16 -0
  160. package/dist/office-share-page.js +85 -0
  161. package/dist/office-share-page.js.map +1 -0
  162. package/dist/office-share-service.d.ts +91 -0
  163. package/dist/office-share-service.js +176 -0
  164. package/dist/office-share-service.js.map +1 -0
  165. package/dist/office-share.d.ts +258 -0
  166. package/dist/office-share.js +549 -0
  167. package/dist/office-share.js.map +1 -0
  168. package/dist/opencode-usage-scan.d.ts +28 -0
  169. package/dist/opencode-usage-scan.js +92 -0
  170. package/dist/opencode-usage-scan.js.map +1 -0
  171. package/dist/opencode-usage-worker.d.ts +1 -0
  172. package/dist/opencode-usage-worker.js +10 -0
  173. package/dist/opencode-usage-worker.js.map +1 -0
  174. package/dist/outbound-handlers.js +22 -2
  175. package/dist/outbound-handlers.js.map +1 -1
  176. package/dist/outbound-schemas.d.ts +28 -2
  177. package/dist/outbound-schemas.js +29 -2
  178. package/dist/outbound-schemas.js.map +1 -1
  179. package/dist/public-web-gateway.js +16 -2
  180. package/dist/public-web-gateway.js.map +1 -1
  181. package/dist/quickstart-api.js +13 -2
  182. package/dist/quickstart-api.js.map +1 -1
  183. package/dist/quickstart.js +2 -1
  184. package/dist/quickstart.js.map +1 -1
  185. package/dist/remote-card-answer.d.ts +83 -0
  186. package/dist/remote-card-answer.js +208 -0
  187. package/dist/remote-card-answer.js.map +1 -0
  188. package/dist/reply-triggers.d.ts +2 -0
  189. package/dist/reply-triggers.js +3 -0
  190. package/dist/reply-triggers.js.map +1 -0
  191. package/dist/settings-api.d.ts +28 -0
  192. package/dist/settings-api.js +148 -17
  193. package/dist/settings-api.js.map +1 -1
  194. package/dist/settings-change.js +54 -17
  195. package/dist/settings-change.js.map +1 -1
  196. package/dist/settings-effect.js +12 -3
  197. package/dist/settings-effect.js.map +1 -1
  198. package/dist/settings-instance-patch.js +4 -1
  199. package/dist/settings-instance-patch.js.map +1 -1
  200. package/dist/setup-form.d.ts +1 -1
  201. package/dist/setup-form.js +55 -6
  202. package/dist/setup-form.js.map +1 -1
  203. package/dist/setup-host.d.ts +9 -0
  204. package/dist/setup-host.js +127 -6
  205. package/dist/setup-host.js.map +1 -1
  206. package/dist/setup-signin-assets.d.ts +2 -0
  207. package/dist/setup-signin-assets.js +6 -0
  208. package/dist/setup-signin-assets.js.map +1 -0
  209. package/dist/setup-wizard.js +2 -0
  210. package/dist/setup-wizard.js.map +1 -1
  211. package/dist/start-attempt.d.ts +9 -5
  212. package/dist/start-attempt.js +27 -8
  213. package/dist/start-attempt.js.map +1 -1
  214. package/dist/start-failure-chat.d.ts +4 -0
  215. package/dist/start-failure-chat.js +23 -6
  216. package/dist/start-failure-chat.js.map +1 -1
  217. package/dist/start-failure-notice.d.ts +4 -0
  218. package/dist/start-failure-notice.js +8 -0
  219. package/dist/start-failure-notice.js.map +1 -1
  220. package/dist/start-failure.d.ts +25 -0
  221. package/dist/start-failure.js +75 -2
  222. package/dist/start-failure.js.map +1 -1
  223. package/dist/structured-signin-transport.d.ts +8 -0
  224. package/dist/structured-signin-transport.js +79 -0
  225. package/dist/structured-signin-transport.js.map +1 -0
  226. package/dist/structured-signin.d.ts +131 -0
  227. package/dist/structured-signin.js +388 -0
  228. package/dist/structured-signin.js.map +1 -0
  229. package/dist/tool-permissions.js +12 -0
  230. package/dist/tool-permissions.js.map +1 -1
  231. package/dist/topic-commands.js +6 -2
  232. package/dist/topic-commands.js.map +1 -1
  233. package/dist/transcript-sources.d.ts +26 -2
  234. package/dist/transcript-sources.js +103 -40
  235. package/dist/transcript-sources.js.map +1 -1
  236. package/dist/turn-reply-guard.d.ts +25 -0
  237. package/dist/turn-reply-guard.js +111 -12
  238. package/dist/turn-reply-guard.js.map +1 -1
  239. package/dist/types.d.ts +46 -9
  240. package/dist/ui/backend-signin.js +68 -12
  241. package/dist/ui/chat-ambient.js +1 -1
  242. package/dist/ui/chat-effects.js +4 -4
  243. package/dist/ui/chat-render.js +5 -2
  244. package/dist/ui/chat-strings.js +4 -4
  245. package/dist/ui/chat-thread.js +2 -2
  246. package/dist/ui/first-run.js +2 -2
  247. package/dist/ui/fleet-canvas-view.js +114 -0
  248. package/dist/ui/fleet-canvas.js +15 -77
  249. package/dist/ui/fleet-office-editor.js +94 -14
  250. package/dist/ui/fleet-office-layout.js +235 -0
  251. package/dist/ui/fleet-office-model.js +12 -6
  252. package/dist/ui/fleet-office-overview.js +167 -0
  253. package/dist/ui/fleet-office-pack.d.ts +44 -0
  254. package/dist/ui/fleet-office-pack.js +352 -37
  255. package/dist/ui/fleet-office-skin.js +220 -36
  256. package/dist/ui/fleet-office-store.js +112 -7
  257. package/dist/ui/fleet-office-view.js +155 -0
  258. package/dist/ui/fleet-office-zones.js +264 -42
  259. package/dist/ui/fleet-office.js +957 -160
  260. package/dist/ui/fleet-usage.js +26 -21
  261. package/dist/ui/office-share-dialog.js +145 -0
  262. package/dist/ui/office-share-page.js +164 -0
  263. package/dist/ui/panel-chat.js +9 -2
  264. package/dist/ui/panel-details.js +2 -2
  265. package/dist/ui/panel-fleet.js +11 -77
  266. package/dist/ui/panel-log.js +4 -4
  267. package/dist/ui/panel-needs.js +4 -4
  268. package/dist/ui/panel-settings.js +608 -167
  269. package/dist/ui/search-dialog.js +26 -7
  270. package/dist/ui/settings-appearance.js +82 -29
  271. package/dist/ui/settings-apply.js +42 -7
  272. package/dist/ui/settings-dialogs.js +76 -23
  273. package/dist/ui/settings-draft.js +51 -0
  274. package/dist/ui/settings-guests.js +255 -79
  275. package/dist/ui/settings-learn.js +2 -2
  276. package/dist/ui/settings-model.js +16 -6
  277. package/dist/ui/settings-registry.js +146 -0
  278. package/dist/ui/settings-strings.js +116 -44
  279. package/dist/ui/settings-web-authority.js +34 -23
  280. package/dist/ui/shared/app-i18n.js +18 -2
  281. package/dist/ui/shared/app-nav.js +10 -5
  282. package/dist/ui/shared/app-prefs.js +80 -2
  283. package/dist/ui/shared/app-route.js +39 -5
  284. package/dist/ui/shared/app-shell.js +73 -10
  285. package/dist/ui/shared/app-stream.js +3 -1
  286. package/dist/ui/shared/app.css +307 -17
  287. package/dist/ui/shared/app.js +3 -0
  288. package/dist/ui/shared/effect-stock-trust.js +1 -1
  289. package/dist/ui/shared/identity-color.js +4 -4
  290. package/dist/ui/shared/office/cozy.png +0 -0
  291. package/dist/ui/shared/side-panel.js +95 -0
  292. package/dist/ui/shared/signin.js +2 -2
  293. package/dist/ui/shared/ui-dialog.js +6 -1
  294. package/dist/ui/shared/ui-icons.js +2 -0
  295. package/dist/ui/shared/web-authorize.js +13 -12
  296. package/dist/ui/structured-signin.js +115 -0
  297. package/dist/usage-report.d.ts +20 -0
  298. package/dist/usage-report.js +54 -17
  299. package/dist/usage-report.js.map +1 -1
  300. package/dist/usage-rollup.d.ts +9 -1
  301. package/dist/usage-rollup.js +20 -4
  302. package/dist/usage-rollup.js.map +1 -1
  303. package/dist/web-api.d.ts +26 -2
  304. package/dist/web-api.js +361 -5
  305. package/dist/web-api.js.map +1 -1
  306. package/dist/web-auth.js +8 -2
  307. package/dist/web-auth.js.map +1 -1
  308. package/dist/web-backend-login.d.ts +1 -7
  309. package/dist/web-backend-login.js +2 -24
  310. package/dist/web-backend-login.js.map +1 -1
  311. package/dist/web-experimental.d.ts +1 -1
  312. package/dist/web-experimental.js +1 -1
  313. package/dist/web-experimental.js.map +1 -1
  314. package/dist/web-mod-agent.js +2 -2
  315. package/dist/web-mod-agent.js.map +1 -1
  316. package/dist/web-office-acts.d.ts +173 -0
  317. package/dist/web-office-acts.js +285 -0
  318. package/dist/web-office-acts.js.map +1 -0
  319. package/dist/web-office-skins.d.ts +109 -0
  320. package/dist/web-office-skins.js +299 -0
  321. package/dist/web-office-skins.js.map +1 -0
  322. package/dist/web-office-store.d.ts +8 -2
  323. package/dist/web-office-store.js +77 -14
  324. package/dist/web-office-store.js.map +1 -1
  325. package/dist/web-settings-patch.d.ts +8 -1
  326. package/dist/web-settings-patch.js +65 -5
  327. package/dist/web-settings-patch.js.map +1 -1
  328. package/dist/web-shell-routes.d.ts +4 -2
  329. package/dist/web-shell-routes.js +17 -7
  330. package/dist/web-shell-routes.js.map +1 -1
  331. package/dist/working-recovery.d.ts +104 -0
  332. package/dist/working-recovery.js +298 -0
  333. package/dist/working-recovery.js.map +1 -0
  334. package/dist/working-state-journal.d.ts +5 -1
  335. package/dist/working-state-journal.js +31 -3
  336. package/dist/working-state-journal.js.map +1 -1
  337. package/package.json +3 -2
  338. package/templates/windows-shortcuts.ps1 +155 -140
@@ -3,179 +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
- return ('export PATH=$HOME/.local/bin:$PATH; source $HOME/.nvm/nvm.sh 2>/dev/null; ' + $command)
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
- return ("wsl -d {0} -u {1} -- bash -lc '{2}'" -f (ConvertTo-PsArgument $distro), (ConvertTo-PsArgument $user), (Get-WslAgendCommand 'agend start'))
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
- $url = [regex]::Match($text, 'Sign-in page:\s*(https?://\S+)')
22
- $code = [regex]::Match($text, 'Code:\s*([A-Z2-7]{4}-?[A-Z2-7]{4})\b')
23
- if (-not $url.Success -or -not $code.Success) { return $null }
24
- return @{ Url = $url.Groups[1].Value; Code = $code.Groups[1].Value }
25
- }
26
- function Invoke-OpenDashboard([string]$distro, [string]$user = 'root', [switch]$Wait) {
27
- # agend web --code 失敗時(AgEnD 沒在跑、沒有 token、連不上)會寫到 stderr 並以 1 結束。Windows PowerShell 5.1 會把重導的
28
- # stderr 變成錯誤紀錄,在 ErrorActionPreference=Stop 下直接中止(#2242 審查):取得輸出的這段改用 Continue、每一筆都轉成文字,
29
- # 結束碼不是 0、啟動不了 wsl,都走下面「打不開」的說明。原本的設定在 finally 還原。
30
- $text = ''; $exit = 1
31
- $prevEAP = $ErrorActionPreference
32
- try {
33
- $ErrorActionPreference = 'Continue'
34
- $text = ((& wsl.exe -d $distro -u $user -- bash -lc (Get-WslAgendCommand 'agend web --code') 2>&1) | ForEach-Object { "$_" } | Out-String)
35
- $exit = $LASTEXITCODE
36
- } catch {
37
- $text = "$_"; $exit = 1
38
- } finally {
39
- $ErrorActionPreference = $prevEAP
40
- }
41
- $signIn = if ($exit -eq 0) { Get-DashboardSignIn $text } else { $null }
42
- if (-not $signIn) {
43
- Write-Host " [!!] 現在打不開 AgEnD 儀表板:AgEnD 可能還沒啟動。" -ForegroundColor Yellow
44
- Write-Host (" 稍等一下再試一次;或在 PowerShell 執行:" + (Get-AgendStartHint $distro $user))
45
- if ($Wait) { Read-Host "按 Enter 關閉" }
46
- return $false
47
- }
48
- $copied = $false; try { Set-Clipboard -Value $signIn.Code; $copied = $true } catch { }
49
- $opened = $false; try { Start-Process $signIn.Url; $opened = $true } catch { }
50
- $spaced = ($signIn.Code.ToCharArray() | ForEach-Object { [string]$_ }) -join ' '
51
- Write-Host ""
52
- Write-Host (" ┌──────────────────────────────────────┐") -ForegroundColor Green
53
- Write-Host (" │ 儀表板登入碼: " + $spaced + " │") -ForegroundColor Green
54
- Write-Host (" └──────────────────────────────────────┘") -ForegroundColor Green
55
- if ($opened) { Write-Host " [OK] 登入頁已在瀏覽器打開。" -ForegroundColor Green } else { Write-Host (" 請自己在瀏覽器打開:" + $signIn.Url) }
56
- if ($copied) { Write-Host " [OK] 登入碼已複製:在登入頁的輸入框按 Ctrl+V。這組登入碼只能用一次,幾分鐘內有效。" -ForegroundColor Green }
57
- else { Write-Host " 在登入頁輸入上面的登入碼。這組登入碼只能用一次,幾分鐘內有效。" }
58
- if ($Wait) { Read-Host "按 Enter 關閉" }
59
- return $true
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 }
48
+ }
49
+ function Invoke-OpenDashboard([string]$distro, [string]$user = 'root', [switch]$Wait, [string]$BackendSignins = '') {
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
60
86
  }
61
87
  '@
62
88
  . ([scriptblock]::Create($DASHBOARD_OPENER_FN))
63
-
64
- # 「AgEnD 重新啟動」捷徑(#1853,使用者 2026-10-20 核准):先問,預設不重啟;確定才在安裝時記下的 Linux 和使用者裡執行
65
- # agend restart,接著顯示 agend status,等你按 Enter。WSL 或 AgEnD 不在時直接說明;絕不執行 wsl --shutdown。
66
- # 這段函式的文字同時是捷徑執行的腳本(和儀表板捷徑一樣,安裝程式與捷徑共用同一份)。
67
89
  $RESTART_FN = @'
68
90
  function Invoke-AgendInWsl([string]$distro, [string]$user, [string]$command) {
69
- # 在 WSL 裡以登入 shell 執行一個 agend 指令,回傳 @{ Code; Text }。Linux 的輸出是 UTF-8;stderr 不讓 5.1 中止(#2242)。
70
- $prevEAP = $ErrorActionPreference; $prevEnc = [Console]::OutputEncoding
71
- try {
72
- $ErrorActionPreference = 'Continue'
73
- try { [Console]::OutputEncoding = [Text.Encoding]::UTF8 } catch { }
74
- $text = ((& wsl.exe -d $distro -u $user -- bash -lc (Get-WslAgendCommand $command) 2>&1) | ForEach-Object { "$_" } | Out-String)
75
- return @{ Code = $LASTEXITCODE; Text = $text }
76
- } catch {
77
- return @{ Code = -1; Text = "$_" }
78
- } finally {
79
- $ErrorActionPreference = $prevEAP
80
- try { [Console]::OutputEncoding = $prevEnc } catch { }
81
- }
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
+ }
82
103
  }
83
104
  function Invoke-RestartAgend([string]$distro, [string]$user, [switch]$Wait, [int]$SettleSeconds = 3) {
84
- Write-Host ""
85
- $answer = Read-Host " 確定要重啟 AgEnD 嗎?所有 agent 會重新啟動,正在進行的工作會中斷。(y/N)"
86
- # 只有一個 y 才算同意(y/N、yes 都不算);[string]:沒有輸入時 Read-Host 回傳 $null,而 $null -notmatch '…' 不是 $true。
87
- if (([string]$answer) -notmatch '^\s*[yY]\s*$') {
88
- Write-Host " 沒有重啟。"
89
- if ($Wait) { $null = Read-Host "按 Enter 關閉" }
90
- return 'cancelled'
91
- }
92
- $r = Invoke-AgendInWsl $distro $user 'agend restart'
93
- $result = 'restarted'
94
- if ($r.Code -eq 0) {
95
- Write-Host " [OK] AgEnD 正在重新啟動。" -ForegroundColor Green
96
- } else {
97
- $result = 'failed'
98
- if ($r.Code -eq -1) { Write-Host " [!!] 找不到 WSL(wsl.exe),所以沒有重啟。" -ForegroundColor Yellow }
99
- elseif ($r.Text -match 'Fleet not running') { Write-Host (" [!!] AgEnD 沒有在執行,所以沒有可以重啟的。要啟動它:" + (Get-AgendStartHint $distro $user)) -ForegroundColor Yellow }
100
- elseif ($r.Text -match 'command not found|agend: not found|no such file') { Write-Host (" [!!] 在 {0} 裡找不到 AgEnD(agend 指令),所以沒有重啟。" -f $distro) -ForegroundColor Yellow }
101
- else { Write-Host (" [!!] 沒有重啟成功:{0} 不存在、WSL 沒有啟動,或 AgEnD 回報了錯誤。" -f $distro) -ForegroundColor Yellow }
102
- if ($r.Text.Trim()) { Write-Host (" " + ($r.Text.Trim() -replace "`r?`n", "`n ")) }
103
- }
104
- if ($result -eq 'restarted') {
105
- Start-Sleep -Seconds $SettleSeconds
106
- Write-Host ""
107
- $s = Invoke-AgendInWsl $distro $user 'agend status'
108
- if ($s.Text.Trim()) { Write-Host (" " + ($s.Text.Trim() -replace "`r?`n", "`n ")) }
109
- }
110
- if ($Wait) { $null = Read-Host "按 Enter 關閉" }
111
- 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
112
132
  }
113
133
  '@
114
134
  . ([scriptblock]::Create($RESTART_FN))
115
-
116
- # 捷徑執行的腳本:共用的函式加上一行呼叫(UTF-8 有 BOM:Windows PowerShell 5.1 才會正確顯示中文)。Linux 與使用者是安裝時記下的。
117
- # 捷徑腳本印出的第一行:它要打開的 Linux 和使用者,指錯了一眼就看得出來。
118
135
  function Get-ShortcutTargetLine([string]$distro, [string]$user) {
119
- return ('Write-Host ("AgEnD(Linux:{0},使用者:{1})" -f ' + (ConvertTo-PsLiteral $distro) + ', ' + (ConvertTo-PsLiteral $user) + ')')
136
+ return ('Write-Host ("AgEnD(Linux:{0},使用者:{1})" -f ' + (ConvertTo-PsLiteral $distro) + ', ' + (ConvertTo-PsLiteral $user) + ')')
120
137
  }
121
138
  function Get-DashboardOpenerScript([string]$distro, [string]$user) {
122
- 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")
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")
123
140
  }
124
141
  function Get-RestartScript([string]$distro, [string]$user) {
125
- 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")
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")
126
143
  }
127
- # 安裝時記下的 Linux 與使用者(%LOCALAPPDATA%\AgEnD\install.json):捷徑、重新執行安裝指令時的快速路徑都讀它。
128
144
  function Get-AgendShortcutDir { return (Join-Path $env:LOCALAPPDATA 'AgEnD') }
129
145
  function Read-InstallRecord {
130
- try {
131
- $r = Get-Content -Raw -LiteralPath (Join-Path (Get-AgendShortcutDir) 'install.json') -ErrorAction Stop | ConvertFrom-Json
132
- if ($r.distro -and $r.user) { return @{ Distro = [string]$r.distro; User = [string]$r.user } }
133
- } catch { }
134
- return $null
135
- }
136
- # install.json 已經指向另一個 Linux 或使用者時回傳那筆紀錄(例如 AgEnD 專用的 Linux 和原本的 Ubuntu),否則 $null。
137
- # 捷徑絕不悄悄改指向: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
+ }
138
152
  function Get-InstallRecordConflict([string]$distro, [string]$user) {
139
- $record = Read-InstallRecord
140
- # WSL 的名稱不分大小寫;Linux 的使用者名稱分(Han 和 han 是兩個人,#2279 審查)。
141
- if ($record -and ($record.Distro -ne $distro -or $record.User -cne $user)) { return $record }
142
- return $null
153
+ $record = Read-InstallRecord
154
+ if ($record -and ($record.Distro -ne $distro -or $record.User -cne $user)) { return $record }
155
+ return $null
143
156
  }
144
- # 真正寫入前再讀一次:詢問時看到的是 $seen($null:當時沒有衝突)。現在沒有衝突,或衝突的還是同一個,才可以寫;
145
- # 在等回答的時候被別的安裝程式或終端機改掉了,就不寫(#2279 審查)。
146
157
  function Test-InstallRecordAsSeen($seen, [string]$distro, [string]$user) {
147
- $now = Get-InstallRecordConflict $distro $user
148
- if ($null -eq $now) { return $true }
149
- return ($null -ne $seen -and $now.Distro -eq $seen.Distro -and $now.User -ceq $seen.User)
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)
161
+ }
162
+ function Get-ShortcutCommand([string]$file) {
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 }
150
168
  }
151
- # 一個桌面捷徑:腳本寫在 %LOCALAPPDATA%\AgEnD,捷徑以 Windows PowerShell 執行它(-ExecutionPolicy Bypass 只對那個行程)。
152
169
  function New-AgendShortcut([string]$name, [string]$scriptName, [string]$scriptText, [string]$description) {
153
- $dir = Get-AgendShortcutDir
154
- New-Item -ItemType Directory -Path $dir -Force | Out-Null
155
- $file = Join-Path $dir $scriptName
156
- [IO.File]::WriteAllText($file, $scriptText, (New-Object System.Text.UTF8Encoding $true))
157
- $lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) ($name + '.lnk')
158
- $shell = New-Object -ComObject WScript.Shell
159
- $sc = $shell.CreateShortcut($lnk)
160
- $sc.TargetPath = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
161
- $sc.Arguments = ('-NoProfile -ExecutionPolicy Bypass -File "{0}"' -f $file)
162
- $sc.Description = $description
163
- $sc.Save()
164
- return $lnk
165
- }
166
- # 建立(或更新)兩個桌面捷徑、記下 Linux 與使用者。兩個各自建立,一個失敗不會擋住另一個;回傳建立好的捷徑路徑,
167
- # 呼叫端用 Write-ShortcutResult 分清楚兩個都好、只好一個、都沒好(#2252 審查)。兩個都好才在 WSL 裡留記號(agend update
168
- # 之後的提示就不會再出現)。不是 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
+ }
169
184
  function Install-AgendShortcuts([string]$distro, [string]$user) {
170
- if (-not $script:OnWindows) { return @() }
171
- $made = @()
172
- try { $made += New-AgendShortcut 'AgEnD 儀表板' 'open-dashboard.ps1' (Get-DashboardOpenerScript $distro $user) 'AgEnD 網頁儀表板(自動帶入登入碼)' } catch { }
173
- try { $made += New-AgendShortcut 'AgEnD 重新啟動' 'restart-agend.ps1' (Get-RestartScript $distro $user) '重新啟動 AgEnD(會先詢問)' } catch { }
174
- try {
175
- New-Item -ItemType Directory -Path (Get-AgendShortcutDir) -Force | Out-Null
176
- $record = @{ distro = $distro; user = $user } | ConvertTo-Json -Compress
177
- [IO.File]::WriteAllText((Join-Path (Get-AgendShortcutDir) 'install.json'), $record, (New-Object System.Text.UTF8Encoding $false))
178
- 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' }
179
- } catch { }
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 { }
180
195
  return $made
181
196
  }