token-usage-insights 0.9.2 → 0.9.5
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.en.md +130 -4
- package/README.ja.md +130 -4
- package/README.ko.md +130 -4
- package/README.md +130 -4
- package/README.zh-CN.md +130 -4
- package/npm/install.cjs +46 -10
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -277,6 +277,8 @@ Usage:
|
|
|
277
277
|
|
|
278
278
|
The dashboard fully backfills existing `chatSessions` files and resynchronizes them when file size or modification time changes. Chat sessions without token fields are still shown with a token count of 0. Only local chat files are read; cloud sessions, Remote SSH hosts, and `state.vscdb` are not included.
|
|
279
279
|
|
|
280
|
+
**Where cache-read tokens come from**: VS Code's `chatSessions` files only persist the `promptTokens` of the last model call in a request plus the accumulated `completionTokens`; they never record prompt-cache reads. The dashboard therefore also reads the Copilot Chat extension debug log written next to them, `GitHub.copilot-chat/debug-logs/<sessionId>/main.jsonl`, sums `inputTokens`, `outputTokens`, and `cachedTokens` across every model call of the turn, and splits the result into non-cached input, cache read, and output tokens so cost estimates use the cache-read rate. The debug log is controlled by the VS Code setting `github.copilot.chat.agentDebugLog.fileLogging.enabled` (already enabled by experiment for some users) and keeps only the 50 most recent sessions by default. Sessions without a debug log fall back to VS Code's own token fields and show 0 cache reads.
|
|
281
|
+
|
|
280
282
|
If VS Code uses `--user-data-dir` or Portable Mode, specify a custom data root for the dashboard:
|
|
281
283
|
|
|
282
284
|
macOS / Linux:
|
|
@@ -567,8 +569,26 @@ curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/s
|
|
|
567
569
|
|
|
568
570
|
This downloads the installed version and immediately enables `token-usage-insights.service`; you do not need to build or edit a systemd file yourself.
|
|
569
571
|
|
|
572
|
+
### macOS: install and enable the launchd LaunchAgent with one command
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
This installs `com.tokenusageinsights.plist` into `~/Library/LaunchAgents/` and loads it immediately; stdout and stderr logs are located in `~/Library/Logs/`.
|
|
579
|
+
|
|
580
|
+
### Windows: install and enable background service with one command (Task Scheduler)
|
|
581
|
+
|
|
582
|
+
```powershell
|
|
583
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
This registers the `TokenUsageInsights_<username>` task in Windows Task Scheduler for the current user and starts it immediately; it starts automatically at user logon in the background, with logs in the installation `logs\` directory (default `%LOCALAPPDATA%\TokenUsageInsights\logs\`).
|
|
587
|
+
|
|
570
588
|
### Manage the service
|
|
571
589
|
|
|
590
|
+
Linux:
|
|
591
|
+
|
|
572
592
|
```bash
|
|
573
593
|
systemctl --user status token-usage-insights.service
|
|
574
594
|
journalctl --user -u token-usage-insights.service -n 50 -f
|
|
@@ -576,6 +596,100 @@ systemctl --user restart token-usage-insights.service
|
|
|
576
596
|
systemctl --user stop token-usage-insights.service
|
|
577
597
|
```
|
|
578
598
|
|
|
599
|
+
macOS:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
launchctl print gui/$(id -u)/com.tokenusageinsights
|
|
603
|
+
launchctl kickstart -k gui/$(id -u)/com.tokenusageinsights
|
|
604
|
+
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.tokenusageinsights.plist
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Windows PowerShell:
|
|
608
|
+
|
|
609
|
+
```powershell
|
|
610
|
+
# Resolve installation directory (defaults to %LOCALAPPDATA%\TokenUsageInsights, or dynamically resolved from task/shortcut)
|
|
611
|
+
$TaskName = if ($env:USERNAME) { "TokenUsageInsights_$env:USERNAME" } else { "TokenUsageInsights" }
|
|
612
|
+
$InstallDir = $null
|
|
613
|
+
$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
614
|
+
if (-not $Task) {
|
|
615
|
+
$Task = Get-ScheduledTask -TaskName "TokenUsageInsights" -ErrorAction SilentlyContinue
|
|
616
|
+
if ($Task) {
|
|
617
|
+
$TaskName = "TokenUsageInsights"
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if ($Task -and $Task.Actions) {
|
|
621
|
+
foreach ($Action in @($Task.Actions)) {
|
|
622
|
+
if ($Action.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
623
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
624
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
625
|
+
break
|
|
626
|
+
} elseif ($Action.WorkingDirectory) {
|
|
627
|
+
$InstallDir = $Action.WorkingDirectory
|
|
628
|
+
break
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
$StartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) "token-usage-insights.lnk"
|
|
633
|
+
if (!(Test-Path $StartupShortcut)) {
|
|
634
|
+
$StartupShortcut = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs\Startup\token-usage-insights.lnk"
|
|
635
|
+
}
|
|
636
|
+
if (-not $InstallDir -and (Test-Path $StartupShortcut)) {
|
|
637
|
+
$WshShell = New-Object -ComObject WScript.Shell
|
|
638
|
+
$Shortcut = $WshShell.CreateShortcut($StartupShortcut)
|
|
639
|
+
if ($Shortcut.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
640
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
641
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
642
|
+
} elseif ($Shortcut.WorkingDirectory) {
|
|
643
|
+
$InstallDir = $Shortcut.WorkingDirectory
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (-not $InstallDir) {
|
|
647
|
+
$InstallDir = Join-Path $env:LOCALAPPDATA "TokenUsageInsights"
|
|
648
|
+
}
|
|
649
|
+
$TargetExe = "$InstallDir\token-usage-insights.exe".ToLowerInvariant().Replace('/', '\')
|
|
650
|
+
$EscapedDir = [regex]::Escape($InstallDir)
|
|
651
|
+
|
|
652
|
+
# Check service status (Task Scheduler or background process)
|
|
653
|
+
Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
654
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
655
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
656
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
657
|
+
} | Select-Object ProcessId, Name, CommandLine
|
|
658
|
+
|
|
659
|
+
# View logs
|
|
660
|
+
Get-Content (Join-Path $InstallDir "logs\token-usage-insights.out.log") -Tail 50 -Wait
|
|
661
|
+
|
|
662
|
+
# Restart service (scoped to this install directory; compatible with Task Scheduler and Startup folder modes)
|
|
663
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
664
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
665
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
666
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
667
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
668
|
+
if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
|
|
669
|
+
Start-ScheduledTask -TaskName $TaskName
|
|
670
|
+
} elseif (Test-Path $StartupShortcut) {
|
|
671
|
+
Start-Process $StartupShortcut
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
# Stop service (scoped to this install directory)
|
|
675
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
676
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
677
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
678
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
679
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
680
|
+
|
|
681
|
+
# Unregister service
|
|
682
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
683
|
+
Unregister-ScheduledTask -TaskName "TokenUsageInsights" -Confirm:$false -ErrorAction SilentlyContinue
|
|
684
|
+
if (Test-Path $StartupShortcut) {
|
|
685
|
+
Remove-Item $StartupShortcut -Force -ErrorAction SilentlyContinue
|
|
686
|
+
}
|
|
687
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
688
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
689
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
690
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
691
|
+
```
|
|
692
|
+
|
|
579
693
|
* * *
|
|
580
694
|
|
|
581
695
|
## Installation options and manual installation
|
|
@@ -592,7 +706,7 @@ Linux / macOS:
|
|
|
592
706
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash
|
|
593
707
|
```
|
|
594
708
|
|
|
595
|
-
To install and enable the
|
|
709
|
+
To install and enable the background service at the same time (systemd on Linux; launchd on macOS):
|
|
596
710
|
|
|
597
711
|
```bash
|
|
598
712
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
@@ -604,6 +718,12 @@ Windows PowerShell:
|
|
|
604
718
|
irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1 | iex
|
|
605
719
|
```
|
|
606
720
|
|
|
721
|
+
To install and enable the background service at the same time on Windows:
|
|
722
|
+
|
|
723
|
+
```powershell
|
|
724
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
725
|
+
```
|
|
726
|
+
|
|
607
727
|
After installation, run (on Linux/macOS, confirm that `bin_dir` is on `PATH`; Windows creates a `.cmd` shim):
|
|
608
728
|
|
|
609
729
|
```bash
|
|
@@ -614,7 +734,7 @@ Environment variables can control the version and installation paths (all option
|
|
|
614
734
|
|
|
615
735
|
| Variable | Platforms | Description |
|
|
616
736
|
| --- | --- | --- |
|
|
617
|
-
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | Release tag to install, such as `v0.9.
|
|
737
|
+
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | Release tag to install, such as `v0.9.5`; defaults to `latest` |
|
|
618
738
|
| `TOKEN_USAGE_INSIGHTS_INSTALL_DIR` | Linux / macOS | Installation directory, passed to `install.sh` |
|
|
619
739
|
| `TOKEN_USAGE_INSIGHTS_BIN_DIR` | Linux / macOS | Executable-link directory, passed to `install.sh` |
|
|
620
740
|
|
|
@@ -633,7 +753,7 @@ If you do not want to execute a remote script directly, download the archive for
|
|
|
633
753
|
- Frontend assets in `static/`
|
|
634
754
|
- The model pricing table `pricing.csv`
|
|
635
755
|
- Status Line and service scripts in `shell/`
|
|
636
|
-
- The `scripts/` directory (including `install.sh`, `install.ps1`, `get.sh`, and `
|
|
756
|
+
- The `scripts/` directory (including `install.sh`, `install.ps1`, `get.sh`, `get.ps1`, and `run-service.ps1`)
|
|
637
757
|
- README, LICENSE, and VERSION
|
|
638
758
|
|
|
639
759
|
Linux or macOS:
|
|
@@ -644,7 +764,7 @@ cd token-usage-insights-<tag>-<target>
|
|
|
644
764
|
./install.sh
|
|
645
765
|
```
|
|
646
766
|
|
|
647
|
-
To install and enable the systemd
|
|
767
|
+
To install and enable the background service (systemd on Linux; launchd on macOS):
|
|
648
768
|
|
|
649
769
|
```bash
|
|
650
770
|
./install.sh --service
|
|
@@ -658,6 +778,12 @@ cd token-usage-insights-<tag>-x86_64-pc-windows-msvc
|
|
|
658
778
|
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
659
779
|
```
|
|
660
780
|
|
|
781
|
+
To install and enable the background service on Windows:
|
|
782
|
+
|
|
783
|
+
```powershell
|
|
784
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Service
|
|
785
|
+
```
|
|
786
|
+
|
|
661
787
|
Custom Windows installation location and port:
|
|
662
788
|
|
|
663
789
|
```powershell
|
package/README.ja.md
CHANGED
|
@@ -277,6 +277,8 @@ VS Code Stable と Insiders に対応しています:
|
|
|
277
277
|
|
|
278
278
|
既存の `chatSessions` ファイルは完全に取り込み、ファイルサイズまたは更新日時が変わると再同期します。Token フィールドのないチャット Session も表示されますが、Token 数は 0 です。読み取るのはローカルのチャットファイルだけで、クラウド Session、Remote SSH ホスト、`state.vscdb` は含まれません。
|
|
279
279
|
|
|
280
|
+
**キャッシュ読み取り Token の取得元**:VS Code の `chatSessions` ファイルには、各リクエストの最後のモデル呼び出しの `promptTokens` と累計の `completionTokens` しか記録されず、Prompt Cache のキャッシュ読み取り数は記録されません。そのためダッシュボードは、同じワークスペースディレクトリに Copilot Chat 拡張機能が書き出すデバッグログ `GitHub.copilot-chat/debug-logs/<sessionId>/main.jsonl` も読み取り、そのターンの全モデル呼び出しの `inputTokens`・`outputTokens`・`cachedTokens` を合計して、非キャッシュ入力・キャッシュ読み取り・出力 Token に分解し、コスト推定にもキャッシュ読み取り単価を適用します。このデバッグログは VS Code 設定 `github.copilot.chat.agentDebugLog.fileLogging.enabled` で制御され(一部ユーザーには実験機能として有効化済み)、既定では最新 50 Session 分のみ保持されます。デバッグログのない Session は VS Code 標準の Token フィールドにフォールバックし、キャッシュ読み取りは 0 と表示されます。
|
|
281
|
+
|
|
280
282
|
VS Code で `--user-data-dir` または Portable Mode を使う場合は、ダッシュボードのカスタムデータルートを指定できます:
|
|
281
283
|
|
|
282
284
|
macOS / Linux:
|
|
@@ -567,8 +569,26 @@ curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/s
|
|
|
567
569
|
|
|
568
570
|
これはインストール版をダウンロードして `token-usage-insights.service` を直ちに有効化します。systemd ファイルを自分でビルドまたは編集する必要はありません。
|
|
569
571
|
|
|
572
|
+
### macOS:1 行で launchd LaunchAgent をインストールして有効化
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
これは `com.tokenusageinsights.plist` を `~/Library/LaunchAgents/` にインストールして直ちにロードします。標準出力とエラーログは `~/Library/Logs/` に出力されます。
|
|
579
|
+
|
|
580
|
+
### Windows:1 行でバックグラウンド常駐サービス(タスクスケジューラ)をインストールして有効化
|
|
581
|
+
|
|
582
|
+
```powershell
|
|
583
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
これは Windows タスクスケジューラ(Task Scheduler)に現在のユーザー専用の `TokenUsageInsights_<username>` タスクを登録して直ちに起動します。ユーザーログイン時に自動的にバックグラウンドで実行され、標準出力とエラーログはインストールディレクトリ配下の `logs\`(デフォルトは `%LOCALAPPDATA%\TokenUsageInsights\logs\`)に出力されます。
|
|
587
|
+
|
|
570
588
|
### サービスを管理
|
|
571
589
|
|
|
590
|
+
Linux:
|
|
591
|
+
|
|
572
592
|
```bash
|
|
573
593
|
systemctl --user status token-usage-insights.service
|
|
574
594
|
journalctl --user -u token-usage-insights.service -n 50 -f
|
|
@@ -576,6 +596,100 @@ systemctl --user restart token-usage-insights.service
|
|
|
576
596
|
systemctl --user stop token-usage-insights.service
|
|
577
597
|
```
|
|
578
598
|
|
|
599
|
+
macOS:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
launchctl print gui/$(id -u)/com.tokenusageinsights
|
|
603
|
+
launchctl kickstart -k gui/$(id -u)/com.tokenusageinsights
|
|
604
|
+
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.tokenusageinsights.plist
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Windows PowerShell:
|
|
608
|
+
|
|
609
|
+
```powershell
|
|
610
|
+
# インストールディレクトリを解決(デフォルトは %LOCALAPPDATA%\TokenUsageInsights、またはタスク/ショートカットから動的取得)
|
|
611
|
+
$TaskName = if ($env:USERNAME) { "TokenUsageInsights_$env:USERNAME" } else { "TokenUsageInsights" }
|
|
612
|
+
$InstallDir = $null
|
|
613
|
+
$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
614
|
+
if (-not $Task) {
|
|
615
|
+
$Task = Get-ScheduledTask -TaskName "TokenUsageInsights" -ErrorAction SilentlyContinue
|
|
616
|
+
if ($Task) {
|
|
617
|
+
$TaskName = "TokenUsageInsights"
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if ($Task -and $Task.Actions) {
|
|
621
|
+
foreach ($Action in @($Task.Actions)) {
|
|
622
|
+
if ($Action.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
623
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
624
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
625
|
+
break
|
|
626
|
+
} elseif ($Action.WorkingDirectory) {
|
|
627
|
+
$InstallDir = $Action.WorkingDirectory
|
|
628
|
+
break
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
$StartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) "token-usage-insights.lnk"
|
|
633
|
+
if (!(Test-Path $StartupShortcut)) {
|
|
634
|
+
$StartupShortcut = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs\Startup\token-usage-insights.lnk"
|
|
635
|
+
}
|
|
636
|
+
if (-not $InstallDir -and (Test-Path $StartupShortcut)) {
|
|
637
|
+
$WshShell = New-Object -ComObject WScript.Shell
|
|
638
|
+
$Shortcut = $WshShell.CreateShortcut($StartupShortcut)
|
|
639
|
+
if ($Shortcut.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
640
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
641
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
642
|
+
} elseif ($Shortcut.WorkingDirectory) {
|
|
643
|
+
$InstallDir = $Shortcut.WorkingDirectory
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (-not $InstallDir) {
|
|
647
|
+
$InstallDir = Join-Path $env:LOCALAPPDATA "TokenUsageInsights"
|
|
648
|
+
}
|
|
649
|
+
$TargetExe = "$InstallDir\token-usage-insights.exe".ToLowerInvariant().Replace('/', '\')
|
|
650
|
+
$EscapedDir = [regex]::Escape($InstallDir)
|
|
651
|
+
|
|
652
|
+
# サービス状態を確認(タスクスケジューラまたはバックグラウンドプロセス)
|
|
653
|
+
Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
654
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
655
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
656
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
657
|
+
} | Select-Object ProcessId, Name, CommandLine
|
|
658
|
+
|
|
659
|
+
# ログをリアルタイム確認
|
|
660
|
+
Get-Content (Join-Path $InstallDir "logs\token-usage-insights.out.log") -Tail 50 -Wait
|
|
661
|
+
|
|
662
|
+
# サービスを再起動(このインストールディレクトリに限定、タスクスケジューラとスタートアップフォルダの両方に対応)
|
|
663
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
664
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
665
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
666
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
667
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
668
|
+
if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
|
|
669
|
+
Start-ScheduledTask -TaskName $TaskName
|
|
670
|
+
} elseif (Test-Path $StartupShortcut) {
|
|
671
|
+
Start-Process $StartupShortcut
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
# サービスを停止(このインストールディレクトリに限定)
|
|
675
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
676
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
677
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
678
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
679
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
680
|
+
|
|
681
|
+
# 常駐サービスを登録解除
|
|
682
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
683
|
+
Unregister-ScheduledTask -TaskName "TokenUsageInsights" -Confirm:$false -ErrorAction SilentlyContinue
|
|
684
|
+
if (Test-Path $StartupShortcut) {
|
|
685
|
+
Remove-Item $StartupShortcut -Force -ErrorAction SilentlyContinue
|
|
686
|
+
}
|
|
687
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
688
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
689
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
690
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
691
|
+
```
|
|
692
|
+
|
|
579
693
|
* * *
|
|
580
694
|
|
|
581
695
|
## インストールオプションと手動インストール
|
|
@@ -592,7 +706,7 @@ Linux / macOS:
|
|
|
592
706
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash
|
|
593
707
|
```
|
|
594
708
|
|
|
595
|
-
Linux
|
|
709
|
+
Linux(systemd user service)または macOS(launchd LaunchAgent)で常駐サービスも同時にインストールして有効化する場合:
|
|
596
710
|
|
|
597
711
|
```bash
|
|
598
712
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
@@ -604,6 +718,12 @@ Windows PowerShell:
|
|
|
604
718
|
irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1 | iex
|
|
605
719
|
```
|
|
606
720
|
|
|
721
|
+
Windows PowerShell で常駐サービスも同時にインストールして有効化する場合:
|
|
722
|
+
|
|
723
|
+
```powershell
|
|
724
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
725
|
+
```
|
|
726
|
+
|
|
607
727
|
インストール後に実行します(Linux/macOS では `bin_dir` が `PATH` に含まれることを確認してください。Windows では `.cmd` shim が作成されます):
|
|
608
728
|
|
|
609
729
|
```bash
|
|
@@ -614,7 +734,7 @@ token-usage-insights
|
|
|
614
734
|
|
|
615
735
|
| 変数 | 対応プラットフォーム | 説明 |
|
|
616
736
|
| --- | --- | --- |
|
|
617
|
-
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | `v0.9.
|
|
737
|
+
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | `v0.9.5` のようなインストール対象の Release tag。デフォルトは `latest` |
|
|
618
738
|
| `TOKEN_USAGE_INSIGHTS_INSTALL_DIR` | Linux / macOS | `install.sh` に渡すインストールディレクトリ |
|
|
619
739
|
| `TOKEN_USAGE_INSIGHTS_BIN_DIR` | Linux / macOS | `install.sh` に渡す実行ファイルリンクディレクトリ |
|
|
620
740
|
|
|
@@ -633,7 +753,7 @@ Invoke-WebRequest -Uri https://raw.githubusercontent.com/doggy8088/TokenUsageIns
|
|
|
633
753
|
- `static/` のフロントエンドアセット
|
|
634
754
|
- モデル料金表 `pricing.csv`
|
|
635
755
|
- `shell/` の Status Line およびサービススクリプト
|
|
636
|
-
- `scripts/` ディレクトリ(`install.sh`、`install.ps1`、`get.sh`、`get.ps1` を含む)
|
|
756
|
+
- `scripts/` ディレクトリ(`install.sh`、`install.ps1`、`get.sh`、`get.ps1`、`run-service.ps1` を含む)
|
|
637
757
|
- README、LICENSE、VERSION
|
|
638
758
|
|
|
639
759
|
Linux または macOS:
|
|
@@ -644,7 +764,7 @@ cd token-usage-insights-<tag>-<target>
|
|
|
644
764
|
./install.sh
|
|
645
765
|
```
|
|
646
766
|
|
|
647
|
-
Linux
|
|
767
|
+
Linux(systemd user service)または macOS(launchd LaunchAgent)で常駐サービスをインストールして有効化する場合:
|
|
648
768
|
|
|
649
769
|
```bash
|
|
650
770
|
./install.sh --service
|
|
@@ -658,6 +778,12 @@ cd token-usage-insights-<tag>-x86_64-pc-windows-msvc
|
|
|
658
778
|
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
659
779
|
```
|
|
660
780
|
|
|
781
|
+
Windows でバックグラウンド常駐サービスをインストールして有効化する場合:
|
|
782
|
+
|
|
783
|
+
```powershell
|
|
784
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Service
|
|
785
|
+
```
|
|
786
|
+
|
|
661
787
|
Windows のインストール先とポートをカスタマイズ:
|
|
662
788
|
|
|
663
789
|
```powershell
|
package/README.ko.md
CHANGED
|
@@ -277,6 +277,8 @@ VS Code Stable 및 Insiders를 지원합니다.
|
|
|
277
277
|
|
|
278
278
|
대시보드는 기존 `chatSessions` 파일을 모두 채우고 파일 크기나 수정 시간이 변경되면 다시 동기화합니다. Token 필드가 없는 채팅 Session도 표시되지만 Token 수는 0입니다. 로컬 채팅 파일만 읽으며 클라우드 Session, Remote SSH 호스트 또는 `state.vscdb`는 포함하지 않습니다.
|
|
279
279
|
|
|
280
|
+
**캐시 읽기 Token 출처**: VS Code의 `chatSessions` 파일은 각 요청에서 마지막 모델 호출의 `promptTokens`와 누적 `completionTokens`만 기록하며 Prompt Cache 캐시 읽기 수는 기록하지 않습니다. 따라서 대시보드는 같은 워크스페이스 디렉터리에 Copilot Chat 확장이 기록하는 디버그 로그 `GitHub.copilot-chat/debug-logs/<sessionId>/main.jsonl`도 함께 읽어, 해당 턴의 모든 모델 호출의 `inputTokens`, `outputTokens`, `cachedTokens`를 합산한 뒤 비캐시 입력, 캐시 읽기, 출력 Token으로 나누고 비용 추정에도 캐시 읽기 단가를 적용합니다. 이 디버그 로그는 VS Code 설정 `github.copilot.chat.agentDebugLog.fileLogging.enabled`로 제어되며(일부 사용자는 실험 기능으로 이미 활성화됨) 기본적으로 최근 50개 Session만 보존합니다. 디버그 로그가 없는 Session은 VS Code 기본 Token 필드로 대체되며 캐시 읽기는 0으로 표시됩니다.
|
|
281
|
+
|
|
280
282
|
VS Code에서 `--user-data-dir` 또는 Portable Mode를 사용하는 경우 대시보드의 사용자 지정 데이터 루트를 지정할 수 있습니다.
|
|
281
283
|
|
|
282
284
|
macOS / Linux:
|
|
@@ -567,8 +569,26 @@ curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/s
|
|
|
567
569
|
|
|
568
570
|
이 명령은 설치 버전을 다운로드하고 `token-usage-insights.service`를 즉시 활성화합니다. systemd 파일을 직접 빌드하거나 수정할 필요가 없습니다.
|
|
569
571
|
|
|
572
|
+
### macOS: 한 줄로 launchd LaunchAgent 설치 및 활성화
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
이 명령은 `com.tokenusageinsights.plist`를 `~/Library/LaunchAgents/`에 설치하고 즉시 로드합니다. 표준 출력과 오류 로그는 `~/Library/Logs/`에 저장됩니다.
|
|
579
|
+
|
|
580
|
+
### Windows: 한 줄로 백그라운드 상주 서비스(작업 스케줄러) 설치 및 활성화
|
|
581
|
+
|
|
582
|
+
```powershell
|
|
583
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
이 명령은 Windows 작업 스케줄러(Task Scheduler)에 현재 사용자 전용 `TokenUsageInsights_<username>` 작업을 등록하고 즉시 시작합니다. 사용자가 로그인할 때마다 백그라운드에서 자동으로 실행되며 표준 출력 및 오류 로그는 설치 디렉터리 하위의 `logs\`(기본값은 `%LOCALAPPDATA%\TokenUsageInsights\logs\`)에 저장됩니다.
|
|
587
|
+
|
|
570
588
|
### 서비스 관리
|
|
571
589
|
|
|
590
|
+
Linux:
|
|
591
|
+
|
|
572
592
|
```bash
|
|
573
593
|
systemctl --user status token-usage-insights.service
|
|
574
594
|
journalctl --user -u token-usage-insights.service -n 50 -f
|
|
@@ -576,6 +596,100 @@ systemctl --user restart token-usage-insights.service
|
|
|
576
596
|
systemctl --user stop token-usage-insights.service
|
|
577
597
|
```
|
|
578
598
|
|
|
599
|
+
macOS:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
launchctl print gui/$(id -u)/com.tokenusageinsights
|
|
603
|
+
launchctl kickstart -k gui/$(id -u)/com.tokenusageinsights
|
|
604
|
+
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.tokenusageinsights.plist
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Windows PowerShell:
|
|
608
|
+
|
|
609
|
+
```powershell
|
|
610
|
+
# 설치 디렉터리 확인(기본값은 %LOCALAPPDATA%\TokenUsageInsights, 또는 작업/바로 가기에서 동적 확인)
|
|
611
|
+
$TaskName = if ($env:USERNAME) { "TokenUsageInsights_$env:USERNAME" } else { "TokenUsageInsights" }
|
|
612
|
+
$InstallDir = $null
|
|
613
|
+
$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
614
|
+
if (-not $Task) {
|
|
615
|
+
$Task = Get-ScheduledTask -TaskName "TokenUsageInsights" -ErrorAction SilentlyContinue
|
|
616
|
+
if ($Task) {
|
|
617
|
+
$TaskName = "TokenUsageInsights"
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if ($Task -and $Task.Actions) {
|
|
621
|
+
foreach ($Action in @($Task.Actions)) {
|
|
622
|
+
if ($Action.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
623
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
624
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
625
|
+
break
|
|
626
|
+
} elseif ($Action.WorkingDirectory) {
|
|
627
|
+
$InstallDir = $Action.WorkingDirectory
|
|
628
|
+
break
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
$StartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) "token-usage-insights.lnk"
|
|
633
|
+
if (!(Test-Path $StartupShortcut)) {
|
|
634
|
+
$StartupShortcut = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs\Startup\token-usage-insights.lnk"
|
|
635
|
+
}
|
|
636
|
+
if (-not $InstallDir -and (Test-Path $StartupShortcut)) {
|
|
637
|
+
$WshShell = New-Object -ComObject WScript.Shell
|
|
638
|
+
$Shortcut = $WshShell.CreateShortcut($StartupShortcut)
|
|
639
|
+
if ($Shortcut.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
640
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
641
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
642
|
+
} elseif ($Shortcut.WorkingDirectory) {
|
|
643
|
+
$InstallDir = $Shortcut.WorkingDirectory
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (-not $InstallDir) {
|
|
647
|
+
$InstallDir = Join-Path $env:LOCALAPPDATA "TokenUsageInsights"
|
|
648
|
+
}
|
|
649
|
+
$TargetExe = "$InstallDir\token-usage-insights.exe".ToLowerInvariant().Replace('/', '\')
|
|
650
|
+
$EscapedDir = [regex]::Escape($InstallDir)
|
|
651
|
+
|
|
652
|
+
# 서비스 상태 확인(작업 스케줄러 또는 백그라운드 프로세스)
|
|
653
|
+
Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
654
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
655
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
656
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
657
|
+
} | Select-Object ProcessId, Name, CommandLine
|
|
658
|
+
|
|
659
|
+
# 실시간 로그 확인
|
|
660
|
+
Get-Content (Join-Path $InstallDir "logs\token-usage-insights.out.log") -Tail 50 -Wait
|
|
661
|
+
|
|
662
|
+
# 서비스 다시 시작(해당 설치 디렉터리에 한정, 작업 스케줄러 및 시작프로그램 모드 자동 호환)
|
|
663
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
664
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
665
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
666
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
667
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
668
|
+
if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
|
|
669
|
+
Start-ScheduledTask -TaskName $TaskName
|
|
670
|
+
} elseif (Test-Path $StartupShortcut) {
|
|
671
|
+
Start-Process $StartupShortcut
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
# 서비스 중지(해당 설치 디렉터리에 한정)
|
|
675
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
676
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
677
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
678
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
679
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
680
|
+
|
|
681
|
+
# 상주 서비스 등록 해제
|
|
682
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
683
|
+
Unregister-ScheduledTask -TaskName "TokenUsageInsights" -Confirm:$false -ErrorAction SilentlyContinue
|
|
684
|
+
if (Test-Path $StartupShortcut) {
|
|
685
|
+
Remove-Item $StartupShortcut -Force -ErrorAction SilentlyContinue
|
|
686
|
+
}
|
|
687
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
688
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
689
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
690
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
691
|
+
```
|
|
692
|
+
|
|
579
693
|
* * *
|
|
580
694
|
|
|
581
695
|
## 설치 옵션 및 수동 설치
|
|
@@ -592,7 +706,7 @@ Linux / macOS:
|
|
|
592
706
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash
|
|
593
707
|
```
|
|
594
708
|
|
|
595
|
-
Linux에서
|
|
709
|
+
Linux(systemd user service) 또는 macOS(launchd LaunchAgent)에서 상주 서비스를 함께 설치하고 활성화하려면:
|
|
596
710
|
|
|
597
711
|
```bash
|
|
598
712
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
@@ -604,6 +718,12 @@ Windows PowerShell:
|
|
|
604
718
|
irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1 | iex
|
|
605
719
|
```
|
|
606
720
|
|
|
721
|
+
Windows PowerShell에서 상주 서비스를 함께 설치하고 활성화하려면:
|
|
722
|
+
|
|
723
|
+
```powershell
|
|
724
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
725
|
+
```
|
|
726
|
+
|
|
607
727
|
설치가 끝나면 실행합니다(Linux/macOS는 `bin_dir`가 `PATH`에 포함되는지 확인하고, Windows는 `.cmd` shim을 만듭니다).
|
|
608
728
|
|
|
609
729
|
```bash
|
|
@@ -614,7 +734,7 @@ token-usage-insights
|
|
|
614
734
|
|
|
615
735
|
| 변수 | 대상 플랫폼 | 설명 |
|
|
616
736
|
| --- | --- | --- |
|
|
617
|
-
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | 설치할 Release tag(예: `v0.9.
|
|
737
|
+
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | 설치할 Release tag(예: `v0.9.5`); 기본값은 `latest` |
|
|
618
738
|
| `TOKEN_USAGE_INSIGHTS_INSTALL_DIR` | Linux / macOS | `install.sh`에 전달할 설치 디렉터리 |
|
|
619
739
|
| `TOKEN_USAGE_INSIGHTS_BIN_DIR` | Linux / macOS | `install.sh`에 전달할 실행 파일 링크 디렉터리 |
|
|
620
740
|
|
|
@@ -633,7 +753,7 @@ Invoke-WebRequest -Uri https://raw.githubusercontent.com/doggy8088/TokenUsageIns
|
|
|
633
753
|
- `static/`의 프런트엔드 자산
|
|
634
754
|
- 모델 가격표 `pricing.csv`
|
|
635
755
|
- `shell/` 디렉터리의 Status Line 및 서비스 스크립트
|
|
636
|
-
- `scripts/` 디렉터리(`install.sh`, `install.ps1`, `get.sh`, `get.ps1` 포함)
|
|
756
|
+
- `scripts/` 디렉터리(`install.sh`, `install.ps1`, `get.sh`, `get.ps1`, `run-service.ps1` 포함)
|
|
637
757
|
- README, LICENSE 및 VERSION
|
|
638
758
|
|
|
639
759
|
Linux 또는 macOS:
|
|
@@ -644,7 +764,7 @@ cd token-usage-insights-<tag>-<target>
|
|
|
644
764
|
./install.sh
|
|
645
765
|
```
|
|
646
766
|
|
|
647
|
-
Linux에서
|
|
767
|
+
Linux(systemd user service) 또는 macOS(launchd LaunchAgent)에서 상주 서비스를 설치하고 활성화하려면:
|
|
648
768
|
|
|
649
769
|
```bash
|
|
650
770
|
./install.sh --service
|
|
@@ -658,6 +778,12 @@ cd token-usage-insights-<tag>-x86_64-pc-windows-msvc
|
|
|
658
778
|
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
659
779
|
```
|
|
660
780
|
|
|
781
|
+
Windows에서 백그라운드 상주 서비스를 설치하고 활성화하려면:
|
|
782
|
+
|
|
783
|
+
```powershell
|
|
784
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Service
|
|
785
|
+
```
|
|
786
|
+
|
|
661
787
|
Windows 설치 위치 및 포트 사용자 지정:
|
|
662
788
|
|
|
663
789
|
```powershell
|
package/README.md
CHANGED
|
@@ -277,6 +277,8 @@ COPILOT_APP_DIR="/path/to/copilot-app-data" token-usage-insights
|
|
|
277
277
|
|
|
278
278
|
看板會完整回填現有 `chatSessions` 檔案,也會在檔案大小或修改時間變更時重新同步;沒有 Token 欄位的聊天 Session 仍會顯示,但 Token 數為 0。資料只讀取本機聊天檔案,不包含雲端 Session、Remote SSH 主機或 `state.vscdb`。
|
|
279
279
|
|
|
280
|
+
**快取讀取 Token 來源**:VS Code 的 `chatSessions` 檔案只記錄每個請求最後一次模型呼叫的 `promptTokens` 與累計的 `completionTokens`,並不記錄 Prompt Cache 的快取讀取數。看板會另外讀取 Copilot Chat 擴充功能在同一個工作區目錄下寫入的除錯記錄 `GitHub.copilot-chat/debug-logs/<sessionId>/main.jsonl`,把該回合所有模型呼叫的 `inputTokens`、`outputTokens` 與 `cachedTokens` 加總後,拆成非快取輸入、快取讀取與輸出 Token,成本估算也會依快取讀取費率計價。此除錯記錄由 VS Code 設定 `github.copilot.chat.agentDebugLog.fileLogging.enabled` 控制(部分使用者已由實驗功能開啟),且預設只保留最近 50 個 Session 的記錄;沒有除錯記錄的 Session 會回退使用 VS Code 內建的 Token 欄位,快取讀取會顯示為 0。
|
|
281
|
+
|
|
280
282
|
若 VS Code 使用 `--user-data-dir` 或 Portable Mode,可指定看板自訂的資料根目錄:
|
|
281
283
|
|
|
282
284
|
macOS / Linux:
|
|
@@ -582,8 +584,26 @@ curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/s
|
|
|
582
584
|
|
|
583
585
|
這會下載安裝版並立即啟用 `token-usage-insights.service`,不需要自行建置或修改 systemd 檔案。
|
|
584
586
|
|
|
587
|
+
### macOS:一行安裝並啟用 launchd LaunchAgent
|
|
588
|
+
|
|
589
|
+
```bash
|
|
590
|
+
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
這會將 `com.tokenusageinsights.plist` 安裝到 `~/Library/LaunchAgents/` 並立即載入;標準輸出與錯誤日誌位於 `~/Library/Logs/`。
|
|
594
|
+
|
|
595
|
+
### Windows:一行安裝並啟用背景常駐服務(工作排程器)
|
|
596
|
+
|
|
597
|
+
```powershell
|
|
598
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
這會透過 Windows 工作排程器(Task Scheduler)註冊專屬於目前使用者的 `TokenUsageInsights_<username>` 背景工作並立即啟動;使用者每次登入時均會自動於背景執行,標準輸出與錯誤日誌位於安裝目錄下的 `logs\`(預設為 `%LOCALAPPDATA%\TokenUsageInsights\logs\`)。
|
|
602
|
+
|
|
585
603
|
### 管理服務
|
|
586
604
|
|
|
605
|
+
Linux 可使用:
|
|
606
|
+
|
|
587
607
|
```bash
|
|
588
608
|
systemctl --user status token-usage-insights.service
|
|
589
609
|
journalctl --user -u token-usage-insights.service -n 50 -f
|
|
@@ -591,6 +611,100 @@ systemctl --user restart token-usage-insights.service
|
|
|
591
611
|
systemctl --user stop token-usage-insights.service
|
|
592
612
|
```
|
|
593
613
|
|
|
614
|
+
macOS 可使用:
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
launchctl print gui/$(id -u)/com.tokenusageinsights
|
|
618
|
+
launchctl kickstart -k gui/$(id -u)/com.tokenusageinsights
|
|
619
|
+
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.tokenusageinsights.plist
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
Windows PowerShell 可使用:
|
|
623
|
+
|
|
624
|
+
```powershell
|
|
625
|
+
# 解析安裝目錄(預設為 %LOCALAPPDATA%\TokenUsageInsights,或由已註冊排程/捷徑動態解析)
|
|
626
|
+
$TaskName = if ($env:USERNAME) { "TokenUsageInsights_$env:USERNAME" } else { "TokenUsageInsights" }
|
|
627
|
+
$InstallDir = $null
|
|
628
|
+
$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
629
|
+
if (-not $Task) {
|
|
630
|
+
$Task = Get-ScheduledTask -TaskName "TokenUsageInsights" -ErrorAction SilentlyContinue
|
|
631
|
+
if ($Task) {
|
|
632
|
+
$TaskName = "TokenUsageInsights"
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
if ($Task -and $Task.Actions) {
|
|
636
|
+
foreach ($Action in @($Task.Actions)) {
|
|
637
|
+
if ($Action.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
638
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
639
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
640
|
+
break
|
|
641
|
+
} elseif ($Action.WorkingDirectory) {
|
|
642
|
+
$InstallDir = $Action.WorkingDirectory
|
|
643
|
+
break
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
$StartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) "token-usage-insights.lnk"
|
|
648
|
+
if (!(Test-Path $StartupShortcut)) {
|
|
649
|
+
$StartupShortcut = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs\Startup\token-usage-insights.lnk"
|
|
650
|
+
}
|
|
651
|
+
if (-not $InstallDir -and (Test-Path $StartupShortcut)) {
|
|
652
|
+
$WshShell = New-Object -ComObject WScript.Shell
|
|
653
|
+
$Shortcut = $WshShell.CreateShortcut($StartupShortcut)
|
|
654
|
+
if ($Shortcut.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
655
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
656
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
657
|
+
} elseif ($Shortcut.WorkingDirectory) {
|
|
658
|
+
$InstallDir = $Shortcut.WorkingDirectory
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
if (-not $InstallDir) {
|
|
662
|
+
$InstallDir = Join-Path $env:LOCALAPPDATA "TokenUsageInsights"
|
|
663
|
+
}
|
|
664
|
+
$TargetExe = "$InstallDir\token-usage-insights.exe".ToLowerInvariant().Replace('/', '\')
|
|
665
|
+
$EscapedDir = [regex]::Escape($InstallDir)
|
|
666
|
+
|
|
667
|
+
# 檢視服務狀態(工作排程器或背景行程)
|
|
668
|
+
Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
669
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
670
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
671
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
672
|
+
} | Select-Object ProcessId, Name, CommandLine
|
|
673
|
+
|
|
674
|
+
# 檢視即時日誌
|
|
675
|
+
Get-Content (Join-Path $InstallDir "logs\token-usage-insights.out.log") -Tail 50 -Wait
|
|
676
|
+
|
|
677
|
+
# 重啟服務(僅限此安裝目錄,自動相容工作排程器與啟動資料夾模式)
|
|
678
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
679
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
680
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
681
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
682
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
683
|
+
if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
|
|
684
|
+
Start-ScheduledTask -TaskName $TaskName
|
|
685
|
+
} elseif (Test-Path $StartupShortcut) {
|
|
686
|
+
Start-Process $StartupShortcut
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
# 停止服務(僅限此安裝目錄)
|
|
690
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
691
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
692
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
693
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
694
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
695
|
+
|
|
696
|
+
# 解除安裝常駐服務
|
|
697
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
698
|
+
Unregister-ScheduledTask -TaskName "TokenUsageInsights" -Confirm:$false -ErrorAction SilentlyContinue
|
|
699
|
+
if (Test-Path $StartupShortcut) {
|
|
700
|
+
Remove-Item $StartupShortcut -Force -ErrorAction SilentlyContinue
|
|
701
|
+
}
|
|
702
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
703
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
704
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
705
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
706
|
+
```
|
|
707
|
+
|
|
594
708
|
* * *
|
|
595
709
|
|
|
596
710
|
## 安裝選項與手動安裝
|
|
@@ -617,7 +731,7 @@ Linux / macOS:
|
|
|
617
731
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash
|
|
618
732
|
```
|
|
619
733
|
|
|
620
|
-
Linux
|
|
734
|
+
Linux(systemd user service)或 macOS(launchd LaunchAgent)如需同時安裝並啟用常駐服務:
|
|
621
735
|
|
|
622
736
|
```bash
|
|
623
737
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
@@ -629,6 +743,12 @@ Windows PowerShell:
|
|
|
629
743
|
irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1 | iex
|
|
630
744
|
```
|
|
631
745
|
|
|
746
|
+
Windows PowerShell 如需同時安裝並啟用常駐服務:
|
|
747
|
+
|
|
748
|
+
```powershell
|
|
749
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
750
|
+
```
|
|
751
|
+
|
|
632
752
|
安裝完成後即可執行(Linux/macOS 需確認 `bin_dir` 已加入 `PATH`;Windows 會建立 `.cmd` shim):
|
|
633
753
|
|
|
634
754
|
```bash
|
|
@@ -639,7 +759,7 @@ token-usage-insights
|
|
|
639
759
|
|
|
640
760
|
| 變數 | 適用平台 | 說明 |
|
|
641
761
|
| --- | --- | --- |
|
|
642
|
-
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | 指定要安裝的 Release tag,例如 `v0.9.
|
|
762
|
+
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | 指定要安裝的 Release tag,例如 `v0.9.5`。預設 `latest` |
|
|
643
763
|
| `TOKEN_USAGE_INSIGHTS_INSTALL_DIR` | Linux / macOS | 安裝目錄,會轉交給 `install.sh` |
|
|
644
764
|
| `TOKEN_USAGE_INSIGHTS_BIN_DIR` | Linux / macOS | 執行檔連結目錄,會轉交給 `install.sh` |
|
|
645
765
|
|
|
@@ -658,7 +778,7 @@ Invoke-WebRequest -Uri https://raw.githubusercontent.com/doggy8088/TokenUsageIns
|
|
|
658
778
|
- `static/` 前端資產
|
|
659
779
|
- `pricing.csv` 模型費用表
|
|
660
780
|
- `shell/` 目錄下的 Status Line 與服務腳本
|
|
661
|
-
- `scripts/` 目錄(含 `install.sh`、`install.ps1`、`get.sh`、`get.ps1`)
|
|
781
|
+
- `scripts/` 目錄(含 `install.sh`、`install.ps1`、`get.sh`、`get.ps1`、`run-service.ps1`)
|
|
662
782
|
- README、LICENSE 與 VERSION
|
|
663
783
|
|
|
664
784
|
Linux 或 macOS:
|
|
@@ -669,7 +789,7 @@ cd token-usage-insights-<tag>-<target>
|
|
|
669
789
|
./install.sh
|
|
670
790
|
```
|
|
671
791
|
|
|
672
|
-
Linux
|
|
792
|
+
Linux(systemd user service)或 macOS(launchd LaunchAgent)如需安裝並啟用常駐服務:
|
|
673
793
|
|
|
674
794
|
```bash
|
|
675
795
|
./install.sh --service
|
|
@@ -683,6 +803,12 @@ cd token-usage-insights-<tag>-x86_64-pc-windows-msvc
|
|
|
683
803
|
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
684
804
|
```
|
|
685
805
|
|
|
806
|
+
Windows 如需安裝並啟用背景常駐服務:
|
|
807
|
+
|
|
808
|
+
```powershell
|
|
809
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Service
|
|
810
|
+
```
|
|
811
|
+
|
|
686
812
|
自訂 Windows 安裝位置與埠號:
|
|
687
813
|
|
|
688
814
|
```powershell
|
package/README.zh-CN.md
CHANGED
|
@@ -277,6 +277,8 @@ COPILOT_APP_DIR="/path/to/copilot-app-data" token-usage-insights
|
|
|
277
277
|
|
|
278
278
|
看板会完整回填现有的 `chatSessions` 文件,并在文件大小或修改时间变化时重新同步;没有 Token 字段的聊天 Session 仍会显示,但 Token 数为 0。数据只读取本地聊天文件,不包含云端 Session、Remote SSH 主机或 `state.vscdb`。
|
|
279
279
|
|
|
280
|
+
**缓存读取 Token 来源**:VS Code 的 `chatSessions` 文件只记录每个请求最后一次模型调用的 `promptTokens` 与累计的 `completionTokens`,并不记录 Prompt Cache 的缓存读取数。看板会另外读取 Copilot Chat 扩展在同一个工作区目录下写入的调试日志 `GitHub.copilot-chat/debug-logs/<sessionId>/main.jsonl`,把该回合所有模型调用的 `inputTokens`、`outputTokens` 与 `cachedTokens` 加总后,拆成非缓存输入、缓存读取与输出 Token,成本估算也会按缓存读取费率计价。此调试日志由 VS Code 设置 `github.copilot.chat.agentDebugLog.fileLogging.enabled` 控制(部分用户已由实验功能开启),且默认只保留最近 50 个 Session 的记录;没有调试日志的 Session 会回退使用 VS Code 内置的 Token 字段,缓存读取会显示为 0。
|
|
281
|
+
|
|
280
282
|
如果 VS Code 使用 `--user-data-dir` 或 Portable Mode,可以指定看板自定义的数据根目录:
|
|
281
283
|
|
|
282
284
|
macOS / Linux:
|
|
@@ -567,8 +569,26 @@ curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/s
|
|
|
567
569
|
|
|
568
570
|
这会下载安装版并立即启用 `token-usage-insights.service`,不需要自行构建或修改 systemd 文件。
|
|
569
571
|
|
|
572
|
+
### macOS:一行安装并启用 launchd LaunchAgent
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
这会将 `com.tokenusageinsights.plist` 安装到 `~/Library/LaunchAgents/` 并立即加载;标准输出与错误日志位于 `~/Library/Logs/`。
|
|
579
|
+
|
|
580
|
+
### Windows:一行安装并启用背景常驻服务(任务计划程序)
|
|
581
|
+
|
|
582
|
+
```powershell
|
|
583
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
这会通过 Windows 任务计划程序(Task Scheduler)注册专属于当前用户的 `TokenUsageInsights_<username>` 计划任务并立即启动;用户每次登录时均会自动在后台运行,标准输出与错误日志位于安装目录下的 `logs\`(默认为 `%LOCALAPPDATA%\TokenUsageInsights\logs\`)。
|
|
587
|
+
|
|
570
588
|
### 管理服务
|
|
571
589
|
|
|
590
|
+
Linux 可使用:
|
|
591
|
+
|
|
572
592
|
```bash
|
|
573
593
|
systemctl --user status token-usage-insights.service
|
|
574
594
|
journalctl --user -u token-usage-insights.service -n 50 -f
|
|
@@ -576,6 +596,100 @@ systemctl --user restart token-usage-insights.service
|
|
|
576
596
|
systemctl --user stop token-usage-insights.service
|
|
577
597
|
```
|
|
578
598
|
|
|
599
|
+
macOS 可使用:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
launchctl print gui/$(id -u)/com.tokenusageinsights
|
|
603
|
+
launchctl kickstart -k gui/$(id -u)/com.tokenusageinsights
|
|
604
|
+
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.tokenusageinsights.plist
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Windows PowerShell 可使用:
|
|
608
|
+
|
|
609
|
+
```powershell
|
|
610
|
+
# 解析安装目录(默认为 %LOCALAPPDATA%\TokenUsageInsights,或由已注册计划任务/快捷方式动态解析)
|
|
611
|
+
$TaskName = if ($env:USERNAME) { "TokenUsageInsights_$env:USERNAME" } else { "TokenUsageInsights" }
|
|
612
|
+
$InstallDir = $null
|
|
613
|
+
$Task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
614
|
+
if (-not $Task) {
|
|
615
|
+
$Task = Get-ScheduledTask -TaskName "TokenUsageInsights" -ErrorAction SilentlyContinue
|
|
616
|
+
if ($Task) {
|
|
617
|
+
$TaskName = "TokenUsageInsights"
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
if ($Task -and $Task.Actions) {
|
|
621
|
+
foreach ($Action in @($Task.Actions)) {
|
|
622
|
+
if ($Action.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
623
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
624
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
625
|
+
break
|
|
626
|
+
} elseif ($Action.WorkingDirectory) {
|
|
627
|
+
$InstallDir = $Action.WorkingDirectory
|
|
628
|
+
break
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
$StartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) "token-usage-insights.lnk"
|
|
633
|
+
if (!(Test-Path $StartupShortcut)) {
|
|
634
|
+
$StartupShortcut = Join-Path $env:APPDATA "Microsoft\Windows\Start Menu\Programs\Startup\token-usage-insights.lnk"
|
|
635
|
+
}
|
|
636
|
+
if (-not $InstallDir -and (Test-Path $StartupShortcut)) {
|
|
637
|
+
$WshShell = New-Object -ComObject WScript.Shell
|
|
638
|
+
$Shortcut = $WshShell.CreateShortcut($StartupShortcut)
|
|
639
|
+
if ($Shortcut.Arguments -match '(?i)-InstallDir(?:\s+|:)(?:"([^"]+)"|(\S+))') {
|
|
640
|
+
$DetectedInstallDir = if ($Matches[1]) { $Matches[1] } else { $Matches[2] }
|
|
641
|
+
$InstallDir = [Environment]::ExpandEnvironmentVariables($DetectedInstallDir)
|
|
642
|
+
} elseif ($Shortcut.WorkingDirectory) {
|
|
643
|
+
$InstallDir = $Shortcut.WorkingDirectory
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (-not $InstallDir) {
|
|
647
|
+
$InstallDir = Join-Path $env:LOCALAPPDATA "TokenUsageInsights"
|
|
648
|
+
}
|
|
649
|
+
$TargetExe = "$InstallDir\token-usage-insights.exe".ToLowerInvariant().Replace('/', '\')
|
|
650
|
+
$EscapedDir = [regex]::Escape($InstallDir)
|
|
651
|
+
|
|
652
|
+
# 查看服务状态(任务计划程序或后台进程)
|
|
653
|
+
Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
654
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
655
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
656
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
657
|
+
} | Select-Object ProcessId, Name, CommandLine
|
|
658
|
+
|
|
659
|
+
# 查看实时日志
|
|
660
|
+
Get-Content (Join-Path $InstallDir "logs\token-usage-insights.out.log") -Tail 50 -Wait
|
|
661
|
+
|
|
662
|
+
# 重启服务(仅限此安装目录,自动兼容任务计划程序与启动文件夹模式)
|
|
663
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
664
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
665
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
666
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
667
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
668
|
+
if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
|
|
669
|
+
Start-ScheduledTask -TaskName $TaskName
|
|
670
|
+
} elseif (Test-Path $StartupShortcut) {
|
|
671
|
+
Start-Process $StartupShortcut
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
# 停止服务(仅限此安装目录)
|
|
675
|
+
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
|
676
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
677
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
678
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
679
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
680
|
+
|
|
681
|
+
# 卸载常驻服务
|
|
682
|
+
Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
683
|
+
Unregister-ScheduledTask -TaskName "TokenUsageInsights" -Confirm:$false -ErrorAction SilentlyContinue
|
|
684
|
+
if (Test-Path $StartupShortcut) {
|
|
685
|
+
Remove-Item $StartupShortcut -Force -ErrorAction SilentlyContinue
|
|
686
|
+
}
|
|
687
|
+
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object {
|
|
688
|
+
($_.CommandLine -like "*run-service.ps1*" -and $_.CommandLine -match "(?i)[\s`"'\\]$EscapedDir([\\`"'\s]|$)") -or
|
|
689
|
+
($_.ExecutablePath -and ($_.ExecutablePath.ToLowerInvariant().Replace('/', '\') -eq $TargetExe))
|
|
690
|
+
} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
691
|
+
```
|
|
692
|
+
|
|
579
693
|
* * *
|
|
580
694
|
|
|
581
695
|
## 安装选项与手动安装
|
|
@@ -592,7 +706,7 @@ Linux / macOS:
|
|
|
592
706
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash
|
|
593
707
|
```
|
|
594
708
|
|
|
595
|
-
Linux
|
|
709
|
+
Linux(systemd user service)或 macOS(launchd LaunchAgent)如需同时安装并启用常驻服务:
|
|
596
710
|
|
|
597
711
|
```bash
|
|
598
712
|
curl -fsSL https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.sh | bash -s -- --service
|
|
@@ -604,6 +718,12 @@ Windows PowerShell:
|
|
|
604
718
|
irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1 | iex
|
|
605
719
|
```
|
|
606
720
|
|
|
721
|
+
Windows PowerShell 如需同时安装并启用常驻服务:
|
|
722
|
+
|
|
723
|
+
```powershell
|
|
724
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/doggy8088/TokenUsageInsights/main/scripts/get.ps1))) -Service
|
|
725
|
+
```
|
|
726
|
+
|
|
607
727
|
安装完成后即可运行(Linux/macOS 需确认 `bin_dir` 已加入 `PATH`;Windows 会创建 `.cmd` shim):
|
|
608
728
|
|
|
609
729
|
```bash
|
|
@@ -614,7 +734,7 @@ token-usage-insights
|
|
|
614
734
|
|
|
615
735
|
| 变量 | 适用平台 | 说明 |
|
|
616
736
|
| --- | --- | --- |
|
|
617
|
-
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | 指定要安装的 Release tag,例如 `v0.9.
|
|
737
|
+
| `TOKEN_USAGE_INSIGHTS_VERSION` | Linux / macOS / Windows | 指定要安装的 Release tag,例如 `v0.9.5`。默认 `latest` |
|
|
618
738
|
| `TOKEN_USAGE_INSIGHTS_INSTALL_DIR` | Linux / macOS | 安装目录,会传递给 `install.sh` |
|
|
619
739
|
| `TOKEN_USAGE_INSIGHTS_BIN_DIR` | Linux / macOS | 可执行文件链接目录,会传递给 `install.sh` |
|
|
620
740
|
|
|
@@ -633,7 +753,7 @@ Invoke-WebRequest -Uri https://raw.githubusercontent.com/doggy8088/TokenUsageIns
|
|
|
633
753
|
- `static/` 前端资源
|
|
634
754
|
- `pricing.csv` 模型费用表
|
|
635
755
|
- `shell/` 目录下的 Status Line 与服务脚本
|
|
636
|
-
- `scripts/` 目录(含 `install.sh`、`install.ps1`、`get.sh`、`get.ps1`)
|
|
756
|
+
- `scripts/` 目录(含 `install.sh`、`install.ps1`、`get.sh`、`get.ps1`、`run-service.ps1`)
|
|
637
757
|
- README、LICENSE 与 VERSION
|
|
638
758
|
|
|
639
759
|
Linux 或 macOS:
|
|
@@ -644,7 +764,7 @@ cd token-usage-insights-<tag>-<target>
|
|
|
644
764
|
./install.sh
|
|
645
765
|
```
|
|
646
766
|
|
|
647
|
-
Linux
|
|
767
|
+
Linux(systemd user service)或 macOS(launchd LaunchAgent)如需安装并启用常驻服务:
|
|
648
768
|
|
|
649
769
|
```bash
|
|
650
770
|
./install.sh --service
|
|
@@ -658,6 +778,12 @@ cd token-usage-insights-<tag>-x86_64-pc-windows-msvc
|
|
|
658
778
|
powershell -ExecutionPolicy Bypass -File .\install.ps1
|
|
659
779
|
```
|
|
660
780
|
|
|
781
|
+
Windows 如需安装并启用背景常驻服务:
|
|
782
|
+
|
|
783
|
+
```powershell
|
|
784
|
+
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Service
|
|
785
|
+
```
|
|
786
|
+
|
|
661
787
|
自定义 Windows 安装位置与端口号:
|
|
662
788
|
|
|
663
789
|
```powershell
|
package/npm/install.cjs
CHANGED
|
@@ -110,19 +110,53 @@ function run(command, args, options = {}) {
|
|
|
110
110
|
if (result.status !== 0) throw new Error(`命令執行失敗:${command}`);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// 以 .NET ZipFile API 解壓,不依賴 Microsoft.PowerShell.Archive 模組:
|
|
114
|
+
// 從 pwsh 7 啟動 npx 時,powershell.exe 會繼承 PowerShell 7 的 PSModulePath,
|
|
115
|
+
// 導致 Expand-Archive 因 PSEdition 檢查而無法自動載入。
|
|
116
|
+
const WINDOWS_ZIP_SCRIPT = [
|
|
117
|
+
"$ErrorActionPreference = 'Stop'",
|
|
118
|
+
'Add-Type -AssemblyName System.IO.Compression.FileSystem',
|
|
119
|
+
'$root = [System.IO.Path]::GetFullPath($env:TUI_DESTINATION)',
|
|
120
|
+
"if (-not $root.EndsWith([System.IO.Path]::DirectorySeparatorChar)) { $root += [System.IO.Path]::DirectorySeparatorChar }",
|
|
121
|
+
'$zip = [System.IO.Compression.ZipFile]::OpenRead($env:TUI_ARCHIVE)',
|
|
122
|
+
'try {',
|
|
123
|
+
' foreach ($entry in $zip.Entries) {',
|
|
124
|
+
' $target = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($root, $entry.FullName))',
|
|
125
|
+
' if (-not $target.StartsWith($root, [System.StringComparison]::OrdinalIgnoreCase)) { throw "壓縮包含不安全路徑:$($entry.FullName)" }',
|
|
126
|
+
" if ($entry.FullName.EndsWith('/') -or $entry.FullName.EndsWith('\\')) {",
|
|
127
|
+
' [System.IO.Directory]::CreateDirectory($target) | Out-Null',
|
|
128
|
+
' continue',
|
|
129
|
+
' }',
|
|
130
|
+
' [System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($target)) | Out-Null',
|
|
131
|
+
' [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $target, $true)',
|
|
132
|
+
' }',
|
|
133
|
+
'} finally {',
|
|
134
|
+
' $zip.Dispose()',
|
|
135
|
+
'}',
|
|
136
|
+
].join('\n');
|
|
137
|
+
|
|
138
|
+
function windowsPowerShellEnvironment(archive, destination, baseEnvironment = process.env) {
|
|
139
|
+
const env = { ...baseEnvironment, TUI_ARCHIVE: archive, TUI_DESTINATION: destination };
|
|
140
|
+
// 移除從 pwsh 7 繼承的 PSModulePath,讓 Windows PowerShell 5.1 使用自身預設模組路徑。
|
|
141
|
+
for (const key of Object.keys(env)) {
|
|
142
|
+
if (key.toLowerCase() === 'psmodulepath') delete env[key];
|
|
143
|
+
}
|
|
144
|
+
return env;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function extractWindowsZip(archive, destination) {
|
|
148
|
+
// Windows 10 1803 以後內建 bsdtar(tar.exe),可直接解壓 zip。
|
|
149
|
+
const tar = spawnSync('tar', ['-xf', archive, '-C', destination], { stdio: 'inherit' });
|
|
150
|
+
if (!tar.error && tar.status === 0) return;
|
|
151
|
+
run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', WINDOWS_ZIP_SCRIPT], {
|
|
152
|
+
env: windowsPowerShellEnvironment(archive, destination),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
113
156
|
function extract(archive, destination) {
|
|
114
157
|
mkdirSync(destination, { recursive: true });
|
|
115
158
|
if (archive.endsWith('.zip') && process.platform === 'win32') {
|
|
116
|
-
|
|
117
|
-
'powershell.exe',
|
|
118
|
-
[
|
|
119
|
-
'-NoProfile',
|
|
120
|
-
'-NonInteractive',
|
|
121
|
-
'-Command',
|
|
122
|
-
'Expand-Archive -LiteralPath $env:TUI_ARCHIVE -DestinationPath $env:TUI_DESTINATION -Force',
|
|
123
|
-
],
|
|
124
|
-
{ env: { ...process.env, TUI_ARCHIVE: archive, TUI_DESTINATION: destination } },
|
|
125
|
-
);
|
|
159
|
+
extractWindowsZip(archive, destination);
|
|
126
160
|
return;
|
|
127
161
|
}
|
|
128
162
|
run('tar', [archive.endsWith('.tar.gz') ? '-xzf' : '-xf', archive, '-C', destination]);
|
|
@@ -218,6 +252,7 @@ if (require.main === module) {
|
|
|
218
252
|
|
|
219
253
|
module.exports = {
|
|
220
254
|
TARGETS,
|
|
255
|
+
WINDOWS_ZIP_SCRIPT,
|
|
221
256
|
artifactName,
|
|
222
257
|
cargoTarget,
|
|
223
258
|
checksumForArtifact,
|
|
@@ -229,4 +264,5 @@ module.exports = {
|
|
|
229
264
|
releaseBaseUrl,
|
|
230
265
|
sha256,
|
|
231
266
|
verifyChecksum,
|
|
267
|
+
windowsPowerShellEnvironment,
|
|
232
268
|
};
|