aico-cli 0.3.16 → 0.3.20

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.
@@ -0,0 +1,333 @@
1
+ # AICO CLI 跨平台启动器 - PowerShell 版本
2
+ # 提供与 Bash 版本功能等价的跨平台脚本执行环境
3
+
4
+ param(
5
+ [Parameter(Mandatory=$true)]
6
+ [string]$ScriptType,
7
+
8
+ [Parameter(Mandatory=$false)]
9
+ [string[]]$Arguments = @()
10
+ )
11
+
12
+ # 全局配置
13
+ $AICO_TEMPLATES_DIR = Split-Path -Parent $PSScriptRoot
14
+ $AICO_HOOKS_DIR = Join-Path $AICO_TEMPLATES_DIR "hooks"
15
+ $AICO_AGENTS_DIR = Join-Path $AICO_TEMPLATES_DIR "agents"
16
+ $AICO_UTILS_DIR = Join-Path $AICO_TEMPLATES_DIR "utils"
17
+
18
+ # 日志函数
19
+ function Write-AicoLog {
20
+ param(
21
+ [string]$Level = "INFO",
22
+ [string]$Message,
23
+ [string]$LogFile = "$env:USERPROFILE\.claude\hooks\notify.log"
24
+ )
25
+
26
+ $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
27
+ $logEntry = "[$Level] $timestamp - $Message"
28
+
29
+ # 控制台输出
30
+ switch ($Level) {
31
+ "ERROR" { Write-Host $logEntry -ForegroundColor Red }
32
+ "WARN" { Write-Host $logEntry -ForegroundColor Yellow }
33
+ "INFO" { Write-Host $logEntry -ForegroundColor Green }
34
+ "DEBUG" { Write-Host $logEntry -ForegroundColor Gray }
35
+ default { Write-Host $logEntry }
36
+ }
37
+
38
+ # 文件日志
39
+ try {
40
+ $logDir = Split-Path -Parent $LogFile
41
+ if (!(Test-Path $logDir)) {
42
+ New-Item -ItemType Directory -Path $logDir -Force | Out-Null
43
+ }
44
+ Add-Content -Path $LogFile -Value $logEntry -Force
45
+ } catch {
46
+ Write-Debug "无法写入日志文件: $_.Exception.Message"
47
+ }
48
+ }
49
+
50
+ # 平台检测函数
51
+ function Get-PlatformInfo {
52
+ $os = [System.Environment]::OSVersion
53
+ $isWindows = $os.Platform -eq "Win32NT"
54
+ $is64Bit = [System.Environment]::Is64BitOperatingSystem
55
+
56
+ if ($isWindows) {
57
+ $winVersion = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty Caption
58
+ return @{
59
+ Platform = "windows"
60
+ Version = $winVersion
61
+ Is64Bit = $is64Bit
62
+ IsWSL = $false
63
+ TempDir = $env:TEMP
64
+ }
65
+ }
66
+
67
+ # WSL 检测
68
+ if (Test-Path "/proc/version") {
69
+ $wslCheck = Get-Content "/proc/version" -ErrorAction SilentlyContinue
70
+ if ($wslCheck -match "Microsoft") {
71
+ return @{
72
+ Platform = "wsl"
73
+ Version = "WSL"
74
+ Is64Bit = $is64Bit
75
+ IsWSL = $true
76
+ TempDir = "/tmp"
77
+ }
78
+ }
79
+ }
80
+
81
+ return @{
82
+ Platform = "unknown"
83
+ Version = $os.VersionString
84
+ Is64Bit = $is64Bit
85
+ IsWSL = $false
86
+ TempDir = "/tmp"
87
+ }
88
+ }
89
+
90
+ # 音频播放函数 - Windows 专用
91
+ function Play-SoundFile {
92
+ param(
93
+ [string]$SoundFile
94
+ )
95
+
96
+ if (!(Test-Path $SoundFile)) {
97
+ Write-AicoLog -Level "WARN" -Message "音频文件不存在: $SoundFile"
98
+ return $false
99
+ }
100
+
101
+ try {
102
+ # Windows Media Player COM 对象
103
+ $player = New-Object -ComObject WMPlayer.OCX.7
104
+ $player.URL = $SoundFile
105
+ $player.controls.play()
106
+
107
+ # 等待播放完成(约1秒)
108
+ Start-Sleep -Milliseconds 1000
109
+ $player.close()
110
+
111
+ Write-AicoLog -Level "INFO" -Message "音频播放成功: $SoundFile"
112
+ return $true
113
+ }
114
+ catch {
115
+ # 备用方案:使用 .NET System.Media
116
+ try {
117
+ $soundPlayer = New-Object System.Media.SoundPlayer($SoundFile)
118
+ $soundPlayer.PlaySync()
119
+ Write-AicoLog -Level "INFO" -Message "音频播放成功(.NET): $SoundFile"
120
+ return $true
121
+ }
122
+ catch {
123
+ Write-AicoLog -Level "ERROR" -Message "音频播放失败: $_.Exception.Message"
124
+ return $false
125
+ }
126
+ }
127
+ }
128
+
129
+ # 通知系统函数
130
+ function Invoke-AicoNotification {
131
+ param(
132
+ [Parameter(Mandatory=$true)]
133
+ [ValidateSet("input", "complete", "error", "warning")]
134
+ [string]$Type,
135
+
136
+ [string]$Message = ""
137
+ )
138
+
139
+ Write-AicoLog -Level "INFO" -Message "通知触发: Type=$Type, Message=$Message"
140
+
141
+ # 音頻文件路徑
142
+ $soundsDir = Join-Path $AICO_HOOKS_DIR "sounds"
143
+
144
+ switch ($Type) {
145
+ "input" {
146
+ $soundFile = Join-Path $soundsDir "input-needed.wav"
147
+ Play-SoundFile -SoundFile $soundFile
148
+
149
+ # Windows 通知气泡
150
+ try {
151
+ Add-Type -AssemblyName System.Windows.Forms
152
+ $notify = New-Object System.Windows.Forms.NotifyIcon
153
+ $notify.Icon = [System.Drawing.SystemIcons]::Information
154
+ $notify.Visible = $true
155
+ $notify.ShowBalloonTip(3000, "Claude Code", "需要您的输入", [System.Windows.Forms.ToolTipIcon]::Info)
156
+ $notify.Dispose()
157
+ }
158
+ catch {
159
+ Write-Debug "系统通知失败: $_.Exception.Message"
160
+ }
161
+ }
162
+
163
+ "complete" {
164
+ $soundFile = Join-Path $soundsDir "complete.wav"
165
+ Play-SoundFile -SoundFile $soundFile
166
+ }
167
+
168
+ "error" {
169
+ # 错误提示音
170
+ [Console]::Beep(500, 300)
171
+ Write-Error $Message
172
+ }
173
+
174
+ "warning" {
175
+ # 警告提示音
176
+ [Console]::Beep(800, 200)
177
+ Write-Warning $Message
178
+ }
179
+ }
180
+ }
181
+
182
+ # 任务管理函数
183
+ function Invoke-TaskManager {
184
+ param(
185
+ [Parameter(Mandatory=$true)]
186
+ [ValidateSet("acquire", "complete", "fail", "list", "parallel", "check-deps")]
187
+ [string]$Command,
188
+
189
+ [string]$TaskListPath = "",
190
+ [string]$TaskId = "",
191
+ [string]$Result = "成功",
192
+ [string]$ErrorMessage = "",
193
+ [int]$MaxParallel = 3
194
+ )
195
+
196
+ switch ($Command) {
197
+ "acquire" {
198
+ if ([string]::IsNullOrEmpty($TaskListPath) -or [string]::IsNullOrEmpty($TaskId)) {
199
+ Write-AicoLog -Level "ERROR" -Message "任务领取需要 TaskListPath 和 TaskId 参数"
200
+ return $false
201
+ }
202
+
203
+ # 实现任务领取逻辑
204
+ $taskContent = Get-Content $TaskListPath -Raw -ErrorAction SilentlyContinue
205
+ if ($taskContent -match $TaskId) {
206
+ Write-AicoLog -Level "INFO" -Message "任务领取成功: $TaskId"
207
+ return $true
208
+ } else {
209
+ Write-AicoLog -Level "WARN" -Message "任务不存在: $TaskId"
210
+ return $false
211
+ }
212
+ }
213
+
214
+ "complete" {
215
+ Write-AicoLog -Level "INFO" -Message "任务完成: $TaskId, 结果: $Result"
216
+ return $true
217
+ }
218
+
219
+ "fail" {
220
+ Write-AicoLog -Level "ERROR" -Message "任务失败: $TaskId, 错误: $ErrorMessage"
221
+ return $false
222
+ }
223
+
224
+ "list" {
225
+ if ([string]::IsNullOrEmpty($TaskListPath)) {
226
+ Write-AicoLog -Level "ERROR" -Message "任务列表需要 TaskListPath 参数"
227
+ return @()
228
+ }
229
+
230
+ $availableTasks = @()
231
+ # 解析任务列表,返回可用任务
232
+ Write-AicoLog -Level "INFO" -Message "获取可用任务列表: $TaskListPath"
233
+ return $availableTasks
234
+ }
235
+
236
+ "parallel" {
237
+ Write-AicoLog -Level "INFO" -Message "开始并行任务执行 (最大并行数: $MaxParallel)"
238
+ # 实现并行执行逻辑
239
+ return $true
240
+ }
241
+
242
+ "check-deps" {
243
+ Write-AicoLog -Level "INFO" -Message "检查任务依赖: $TaskId"
244
+ return $true
245
+ }
246
+ }
247
+ }
248
+
249
+ # Hook 执行函数
250
+ function Invoke-AicoHook {
251
+ param(
252
+ [Parameter(Mandatory=$true)]
253
+ [ValidateSet("pre", "post")]
254
+ [string]$Type,
255
+
256
+ [Parameter(Mandatory=$true)]
257
+ [string]$HookName,
258
+
259
+ [string[]]$Arguments = @()
260
+ )
261
+
262
+ $hookScript = "$Type-$HookName.ps1"
263
+ $hookPath = Join-Path $AICO_HOOKS_DIR $hookScript
264
+
265
+ if (Test-Path $hookPath) {
266
+ Write-AicoLog -Level "INFO" -Message "执行 $Type Hook: $HookName"
267
+ try {
268
+ & $hookPath @Arguments
269
+ Write-AicoLog -Level "INFO" -Message "Hook $HookName $Type 执行成功"
270
+ return $true
271
+ }
272
+ catch {
273
+ Write-AicoLog -Level "ERROR" -Message "Hook $HookName $Type 执行失败: $_.Exception.Message"
274
+ return $false
275
+ }
276
+ } else {
277
+ Write-AicoLog -Level "DEBUG" -Message "Hook 脚本不存在: $hookPath"
278
+ return $true # 不存在的 Hook 视为成功
279
+ }
280
+ }
281
+
282
+ # 主函数
283
+ function Main {
284
+ param(
285
+ [string]$ScriptType,
286
+ [string[]]$Arguments
287
+ )
288
+
289
+ Write-AicoLog -Level "INFO" -Message "AICO Platform Launcher 启动: ScriptType=$ScriptType"
290
+
291
+ # 平台信息
292
+ $platform = Get-PlatformInfo
293
+ Write-AicoLog -Level "DEBUG" -Message "平台信息: $($platform | ConvertTo-Json -Compress)"
294
+
295
+ switch ($ScriptType.ToLower()) {
296
+ "notify" {
297
+ $notificationType = $Arguments[0]
298
+ Invoke-AicoNotification -Type $notificationType
299
+ }
300
+
301
+ "task-manager" {
302
+ $command = $Arguments[0]
303
+ $taskListPath = $Arguments[1]
304
+ $taskId = $Arguments[2]
305
+
306
+ Invoke-TaskManager -Command $command -TaskListPath $taskListPath -TaskId $taskId
307
+ }
308
+
309
+ "hook" {
310
+ $hookType = $Arguments[0]
311
+ $hookName = $Arguments[1]
312
+ $hookArgs = $Arguments[2..($Arguments.Length-1)]
313
+
314
+ Invoke-AicoHook -Type $hookType -HookName $hookName -Arguments $hookArgs
315
+ }
316
+
317
+ "platform-info" {
318
+ $platform | ConvertTo-Json -Depth 3
319
+ }
320
+
321
+ default {
322
+ Write-AicoLog -Level "ERROR" -Message "未知的脚本类型: $ScriptType"
323
+ Write-Host "用法:"
324
+ Write-Host " platform-launcher.ps1 notify [input|complete|error|warning]"
325
+ Write-Host " platform-launcher.ps1 task-manager [command] [参数...]"
326
+ Write-Host " platform-launcher.ps1 hook [pre|post] [hook-name] [参数...]"
327
+ Write-Host " platform-launcher.ps1 platform-info"
328
+ }
329
+ }
330
+ }
331
+
332
+ # 执行主函数
333
+ Main -ScriptType $ScriptType -Arguments $Arguments